From 5deae6f64e9a654c08098c1c9d3d6c11d85f3b82 Mon Sep 17 00:00:00 2001 From: Nigel-Ecma Date: Sat, 12 Jul 2025 15:50:48 +1200 Subject: [PATCH 1/8] Add support for Index & Range --- .../dependencies/GrammarTestingEnv.tgz | Bin 54839 -> 54631 bytes standard/README.md | 4 + standard/arrays.md | 4 +- standard/clauses.json | 3 +- standard/expressions.md | 203 +- standard/lexical-structure.md | 10 +- standard/ranges.md | 291 ++ standard/standard-library.md | 173 + .../part-I/Reference/sample.gruntree.red.txt | 2 +- .../part-I/Reference/sample.tree.red.txt | 2 +- .../part-I/Reference/sample.tree.svg | 3032 ++++++++--------- .../part-O/Reference/sample.gruntree.red.txt | 6 +- .../part-O/Reference/sample.tree.red.txt | 2 +- .../part-O/Reference/sample.tree.svg | 2672 +++++++-------- .../part-R/Reference/sample.gruntree.red.txt | 6 +- .../part-R/Reference/sample.tree.red.txt | 2 +- .../part-R/Reference/sample.tree.svg | 1782 +++++----- .../Reference/sample.gruntree.red.txt | 4 +- .../v6/RightShift/Reference/sample.stderr.txt | 2 +- .../RightShift/Reference/sample.tree.red.txt | 2 +- .../v6/RightShift/Reference/sample.tree.svg | 538 +-- .../Samples/v8/Element Access/ReadMe.md | 2 +- .../Samples/v8/Index & Range/ReadMe.md | 1 + .../Reference/sample.gruntree.red.txt | 1017 ++++++ .../Index & Range/Reference/sample.stderr.txt | 1 + .../Index & Range/Reference/sample.tokens.txt | 176 + .../Reference/sample.tree.red.txt | 1 + .../Index & Range/Reference/sample.tree.svg | 2285 +++++++++++++ .../v8/Index & Range/_Sample_Options.txt | 1 + .../Samples/v8/Index & Range/sample.cs | 26 + 30 files changed, 8181 insertions(+), 4069 deletions(-) create mode 100644 standard/ranges.md create mode 100644 tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/ReadMe.md create mode 100644 tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.gruntree.red.txt create mode 100644 tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.stderr.txt create mode 100644 tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tokens.txt create mode 100644 tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tree.red.txt create mode 100644 tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tree.svg create mode 100644 tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/_Sample_Options.txt create mode 100644 tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/sample.cs diff --git a/.github/workflows/dependencies/GrammarTestingEnv.tgz b/.github/workflows/dependencies/GrammarTestingEnv.tgz index aa65ce27b2c9a58be2531a1fb716047d135bc398..932ae59a95bc1e4288f5f72d0eb1ded53819af97 100644 GIT binary patch literal 54631 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 E0Jis85C8xG literal 54839 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 | **Subclause** | **Category** | **Operators** | > | ----------------- | ------------------------------- | -------------------------------------------------------| > | [§12.8](expressions.md#128-primary-expressions) | Primary | `x.y` `x?.y` `f(x)` `a[x]` `a?[x]` `x++` `x--` `x!` `new` `typeof` `default` `checked` `unchecked` `delegate` `stackalloc` | -> | [§12.9](expressions.md#129-unary-operators) | Unary | `+` `-` `!x` `~` `++x` `--x` `(T)x` `await x` | +> | [§12.9](expressions.md#129-unary-operators) | Unary | `+` `-` `!x` `~` `^` `++x` `--x` `(T)x` `await x` | +> | §range-operator | Range | `..` | > | [§12.10](expressions.md#1210-arithmetic-operators) | Multiplicative | `*` `/` `%` | > | [§12.10](expressions.md#1210-arithmetic-operators) | Additive | `+` `-` | > | [§12.11](expressions.md#1211-shift-operators) | Shift | `<<` `>>` | @@ -167,10 +168,12 @@ The precedence of an operator is established by the definition of its associated When an operand occurs between two operators with the same precedence, the ***associativity*** of the operators controls the order in which the operations are performed: -- Except for the assignment operators and the null coalescing operator, all binary operators are ***left-associative***, meaning that operations are performed from left to right. +- Except for the assignment operators, the range operator, and the null coalescing operator, all binary operators are ***left-associative***, meaning that operations are performed from left to right. > *Example*: `x + y + z` is evaluated as `(x + y) + z`. *end example* - The assignment operators, the null coalescing operator and the conditional operator (`?:`) are ***right-associative***, meaning that operations are performed from right to left. > *Example*: `x = y = z` is evaluated as `x = (y = z)`. *end example* +- The range operator is ***non-associative***. + > *Example*: `x..y..z` is invalid. *end example* Precedence and associativity can be controlled using parentheses. @@ -182,21 +185,17 @@ All unary and binary operators have predefined implementations. In addition, use The ***overloadable unary operators*** are: -`+ - !` (logical negation only) `~ ++ -- true false` +> `+ - !` (logical negation only) `~ ++ -- true false` -> *Note*: Although `true` and `false` are not used explicitly in expressions (and therefore are not included in the precedence table in [§12.4.2](expressions.md#1242-operator-precedence-and-associativity)), they are considered operators because they are invoked in several expression contexts: Boolean expressions ([§12.24](expressions.md#1224-boolean-expressions)) and expressions involving the conditional ([§12.18](expressions.md#1218-conditional-operator)) and conditional logical operators ([§12.14](expressions.md#1214-conditional-logical-operators)). *end note* - +Only the operators listed above can be overloaded. In particular, it is not possible to overload the null-forgiving operator (postfix `!`, [§12.8.9](expressions.md#1289-null-forgiving-expressions)) or the unary hat operator (prefix `^`, (§hat-operator)). - -> *Note*: The null-forgiving operator (postfix `!`, [§12.8.9](expressions.md#1289-null-forgiving-expressions)) is not an overloadable operator. *end note* +> *Note*: Although `true` and `false` are not used explicitly in expressions (and therefore are not included in the precedence table in [§12.4.2](expressions.md#1242-operator-precedence-and-associativity)), they are considered operators because they are invoked in several expression contexts: Boolean expressions ([§12.24](expressions.md#1224-boolean-expressions)) and expressions involving the conditional ([§12.18](expressions.md#1218-conditional-operator)) and conditional logical operators ([§12.14](expressions.md#1214-conditional-logical-operators)). *end note* The ***overloadable binary operators*** are: -```csharp -+ - * / % & | ^ << >> == != > < <= >= -``` +> `+ - * / % & | ^ << >> == != > < <= >=` -Only the operators listed above can be overloaded. In particular, it is not possible to overload member access, method invocation, or the `=`, `&&`, `||`, `??`, `?:`, `=>`, `checked`, `unchecked`, `new`, `typeof`, `default`, `as`, and `is` operators. +Only the operators listed above can be overloaded. In particular, it is not possible to overload member access, method invocation, or the `..`, `=`, `&&`, `||`, `??`, `?:`, `=>`, `checked`, `unchecked`, `new`, `typeof`, `default`, `as`, and `is` operators. When a binary operator is overloaded, the corresponding compound assignment operator, if any, is also implicitly overloaded. @@ -348,8 +347,8 @@ In both of the above cases, a cast expression can be used to explicitly convert ***Lifted operators*** permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following: -- For the unary operators `+`, `++`, `-`, `--`, `!`(logical negation), and `~`, a lifted form of an operator exists if the operand and result types are both non-nullable value types. The lifted form is constructed by adding a single `?` modifier to the operand and result types. The lifted operator produces a `null` value if the operand is `null`. Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result. -- For the binary operators `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, and `>>`, a lifted form of an operator exists if the operand and result types are all non-nullable value types. The lifted form is constructed by adding a single `?` modifier to each operand and result type. The lifted operator produces a `null` value if one or both operands are `null` (an exception being the `&` and `|` operators of the `bool?` type, as described in [§12.13.5](expressions.md#12135-nullable-boolean--and--operators)). Otherwise, the lifted operator unwraps the operands, applies the underlying operator, and wraps the result. +- For the unary operators `+`, `++`, `-`, `--`, `!` (logical negation), `^`, and `~`, a lifted form of an operator exists if the operand and result types are both non-nullable value types. The lifted form is constructed by adding a single `?` modifier to the operand and result types. The lifted operator produces a `null` value if the operand is `null`. Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result. +- For the binary operators `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `..`, `<<`, and `>>`, a lifted form of an operator exists if the operand and result types are all non-nullable value types. The lifted form is constructed by adding a single `?` modifier to each operand and result type. The lifted operator produces a `null` value if one or both operands are `null` (an exception being the `&` and `|` operators of the `bool?` type, as described in [§12.13.5](expressions.md#12135-nullable-boolean--and--operators)). Otherwise, the lifted operator unwraps the operands, applies the underlying operator, and wraps the result. - For the equality operators `==` and `!=`, a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is `bool`. The lifted form is constructed by adding a single `?` modifier to each operand type. The lifted operator considers two `null` values equal, and a `null` value unequal to any non-`null` value. If both operands are non-`null`, the lifted operator unwraps the operands and applies the underlying operator to produce the `bool` result. - For the relational operators `<`, `>`, `<=`, and `>=`, a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is `bool`. The lifted form is constructed by adding a single `?` modifier to each operand type. The lifted operator produces the value `false` if one or both operands are `null`. Otherwise, the lifted operator unwraps the operands and applies the underlying operator to produce the `bool` result. @@ -1657,7 +1656,7 @@ The *qualified_alias_member* production is defined in [§14.8](namespaces.md#148 A *member_access* is either of the form `E.I` or of the form `E.I`, where `E` is a *primary_expression*, *predefined_type* or *qualified_alias_member,* `I` is a single identifier, and `` is an optional *type_argument_list*. When no *type_argument_list* is specified, consider `e` to be zero. -A *member_access* with a *primary_expression* of type `dynamic` is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). In this case, the compiler classifies the member access as a property access of type `dynamic`. The rules below to determine the meaning of the *member_access* are then applied at run-time, using the run-time type instead of the compile-time type of the *primary_expression*. If this run-time classification leads to a method group, then the member access shall be the *primary_expression* of an *invocation_expression*. +A *member_access* with a *primary_expression* of type `dynamic` is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). In this case, the member access is classified as a property access of type `dynamic`. The rules below to determine the meaning of the *member_access* are then applied at run-time, using the run-time type instead of the compile-time type of the *primary_expression*. If this run-time classification leads to a method group, then the member access shall be the *primary_expression* of an *invocation_expression*. The *member_access* is evaluated and classified as follows: @@ -1952,7 +1951,7 @@ An *invocation_expression* is dynamically bound ([§12.3.3](expressions.md#1233- - The *primary_expression* has compile-time type `dynamic`. - At least one argument of the optional *argument_list* has compile-time type `dynamic`. -In this case, the compiler classifies the *invocation_expression* as a value of type `dynamic`. The rules below to determine the meaning of the *invocation_expression* are then applied at run-time, using the run-time type instead of the compile-time type of those of the *primary_expression* and arguments that have the compile-time type `dynamic`. If the *primary_expression* does not have compile-time type `dynamic`, then the method invocation undergoes a limited compile-time check as described in [§12.6.5](expressions.md#1265-compile-time-checking-of-dynamic-member-invocation). +In this case, the *invocation_expression* is classified as a value of type `dynamic`. The rules below to determine the meaning of the *invocation_expression* are then applied at run-time, using the run-time type instead of the compile-time type of those of the *primary_expression* and arguments that have the compile-time type `dynamic`. If the *primary_expression* does not have compile-time type `dynamic`, then the method invocation undergoes a limited compile-time check as described in [§12.6.5](expressions.md#1265-compile-time-checking-of-dynamic-member-invocation). The *primary_expression* of an *invocation_expression* shall be a method group or a value of a *delegate_type*. If the *primary_expression* is a method group, the *invocation_expression* is a method invocation ([§12.8.10.2](expressions.md#128102-method-invocations)). If the *primary_expression* is a value of a *delegate_type*, the *invocation_expression* is a delegate invocation ([§12.8.10.4](expressions.md#128104-delegate-invocations)). If the *primary_expression* is neither a method group nor a value of a *delegate_type*, a binding-time error occurs. @@ -2198,8 +2197,6 @@ element_access When recognising a *primary_expression* if both the *element_access* and *pointer_element_access* ([§23.6.4](unsafe-code.md#2364-pointer-element-access)) alternatives are applicable then the latter shall be chosen if the embedded *primary_expression* is of pointer type ([§23.3](unsafe-code.md#233-pointer-types)). -The *argument_list* of an *element_access* shall not contain `out` or `ref` arguments. - The *primary_expression* of an *element_access* shall not be an *array_creation_expression* unless it includes an *array_initializer*, or a *stackalloc_expression* unless it includes a *stackalloc_initializer*. > *Note*: This restriction exists to disallow potentially confusing code such as: @@ -2221,29 +2218,91 @@ The *primary_expression* of an *element_access* shall not be an *array_creation_ An *element_access* is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)) if at least one of the following holds: - The *primary_expression* has compile-time type `dynamic`. -- At least one expression of the *argument_list* has compile-time type `dynamic` and the *primary_expression* does not have an array type. +- At least one expression of the *argument_list* has compile-time type `dynamic`. -In this case, the compiler classifies the *element_access* as a value of type `dynamic`. The rules below to determine the meaning of the *element_access* are then applied at run-time, using the run-time type instead of the compile-time type of those of the *primary_expression* and *argument_list* expressions which have the compile-time type `dynamic`. If the *primary_expression* does not have compile-time type `dynamic`, then the element access undergoes a limited compile-time check as described in [§12.6.5](expressions.md#1265-compile-time-checking-of-dynamic-member-invocation). +In this case the compile-time type of the *element_access* depends on the compile-time type of its *primary_expression*: if it has an array type then the compile-time type is the element type of that array type; otherwise the compile-time type is `dynamic` and the *element_access* is classified as a value of type `dynamic`. The rules below to determine the meaning of the *element_access* are then applied at run-time, using the run-time type instead of the compile-time type of those of the *primary_expression* and *argument_list* expressions which have the compile-time type `dynamic`. If the *primary_expression* does not have compile-time type `dynamic`, then the element access undergoes a limited compile-time check as described in [§12.6.5](expressions.md#1265-compile-time-checking-of-dynamic-member-invocation). -If the *primary_expression* of an *element_access* is a value of an *array_type*, the *element_access* is an array access ([§12.8.12.2](expressions.md#128122-array-access)). Otherwise, the *primary_expression* shall be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the *element_access* is an indexer access ([§12.8.12.3](expressions.md#128123-indexer-access)). +> *Example*: +> +> ```csharp +> var index = (dynamic)1; // index has compile-time type dynamic +> int[] a = {0, 1, 2}; +> var a_elem = a[index]; // dynamically bound, a_elem has compile-time type int +> string s = "012"; +> var s_elem = s[index]; // dynamcially bound, s_elem has compile-time type dynamic +> ``` +> +> *end example* + +If the *primary_expression* of an *element_access* is: + +- a value of *array_type*, the *element_access* is an array access ([§12.8.12.2](expressions.md#128122-array-access)); +- a value of `string` type, the *element_access* is a string access (§string-access); +- otherwise, the *primary_expression* shall be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the *element_access* is an indexer access ([§12.8.12.3](expressions.md#128123-indexer-access)). #### 12.8.12.2 Array access -For an array access, the *primary_expression* of the *element_access* shall be a value of an *array_type*. Furthermore, the *argument_list* of an array access shall not contain named arguments. The number of expressions in the *argument_list* shall be the same as the rank of the *array_type*, and each expression shall be of type `int`, `uint`, `long`, or `ulong,` or shall be implicitly convertible to one or more of these types. +For an array access the *argument_list* shall not contain named arguments or by-reference arguments (§15.6.2.3). + +The number of expressions in the *argument_list* shall be the same as the rank of the *array_type*, and each expression shall be: + +- of type `int`, `uint`, `long`, or `ulong`; or +- for single rank array access only of compile-time type `Index` or `Range`; or +- shall be implicitly convertible to one or more of the above types. -The result of evaluating an array access is a variable of the element type of the array, namely the array element selected by the values of the expressions in the *argument_list*. +Indexing a single rank array using an expression of type `Index` or `Range` is *not* supported if the access is dynamically-bound (§12.8.12.1). -The run-time processing of an array access of the form `P[A]`, where `P` is a *primary_expression* of an *array_type* and `A` is an *argument_list*, consists of the following steps: +The run-time processing of an array access of the form `P[A]`, where `P` is a *primary_expression* of an *array_type* and `A` is an *argument_list* of index expressions, consists of the following steps: - `P` is evaluated. If this evaluation causes an exception, no further steps are executed. -- The index expressions of the *argument_list* are evaluated in order, from left to right. Following evaluation of each index expression, an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) to one of the following types is performed: `int`, `uint`, `long`, `ulong`. The first type in this list for which an implicit conversion exists is chosen. For instance, if the index expression is of type `short` then an implicit conversion to `int` is performed, since implicit conversions from `short` to `int` and from `short` to `long` are possible. If evaluation of an index expression or the subsequent implicit conversion causes an exception, then no further index expressions are evaluated and no further steps are executed. +- For each index expression in the *argument_list* in order, from left to right: + - The index expression is evaluated, let the type of the resultant value be *T*; + - This value is then converted to the first of the types: `int`, `uint`, `long`, `ulong`, or for static bound single rank array access only `Index` or `Range`; for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) from *T* exists. + - If evaluation of an index expression or the subsequent implicit conversion causes an exception, then no further index expressions are evaluated and no further steps are executed. - The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. -- The value of each expression in the *argument_list* is checked against the actual bounds of each dimension of the array instance referenced by `P`. If one or more values are out of range, a `System.IndexOutOfRangeException` is thrown and no further steps are executed. -- The location of the array element given by the index expressions is computed, and this location becomes the result of the array access. +- If the preceding steps have produced a single index value of type `Range` then: + - The result of evaluating the array access is a new array. + - The starting and ending indicies of the `Range` value are determined with respect to the length of the array referenced by `P`. + - If either index is out of range of the bounds of the array referenced by `P`, or the ending index comes before the starting index, then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. + - A new array is created from a shallow copy of the elements of `P` from the starting to ending indicies, this is commonly referred to as a *slice*. This array becomes the results of the array access. + +> > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses (§12.8.12.3) which may, but need not, support assignment to a range of indicies specified by a `Range` value. *end note* + +- Otherwise: + - The result of evaluating the array access is a variable reference (§9.5) of the element type of the array. + - The value of each expression in the *argument_list* is checked against the actual bounds of each dimension of the array instance referenced by `P`. If one or more values are out of range, a `System.IndexOutOfRangeException` is thrown and no further steps are executed. + - The variable reference of the array element given by the index expressions is computed, and this becomes the result of the array access. + +#### §string-access String access + +For a string access the *argument_list* of an string access shall contain a single unnamed value argument (§15.6.2.2) which shall be of type: + +- of type `int`; or +- of compile-time type `Index` or `Range`; or +- shall be implicitly convertible to one or more of the above types. + +Indexing a string using an expression of type `Index` or `Range` is *not* supported if the access is dynamically-bound (§12.8.12.1). + +The run-time processing of a string access of the form `P[A]`, where `P` is a *primary_expression* of `string` type and `A` is a single expression, consists of the following steps: + +- `P` is evaluated. If this evaluation causes an exception, no further steps are executed. +- The index expression is evaluated, let the type of the resultant value be *T*; +- This value is then converted to the first of the types: `int`, or for static bound expressions only `Index` or `Range`; for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) from *T* exists. +- If evaluation of an index expression or the subsequent implicit conversion causes an exception, then no further index expressions are evaluated and no further steps are executed. +- The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. +- If the preceding steps have produced an index value of type `Range` then: + - The result of evaluating the string access is a value of `string` type. + - The starting and ending indicies of the `Range` value are determined with respect to the length of the string referenced by `P`. + - If either index is out of range of the bounds of the string referenced by `P`, or the ending index comes before the starting index, then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. + - The result of the string access is a new string formed from a shallow copy of the characters of `P` from the starting to ending indicies, this is commonly referred to as a *substring*. +- Otherwise: + - The result of evaluating the string access is a value of `char` type. + - The value of the converted index expression is checked against the actual bounds of the string instance referenced by `P`. If the value is out of range, a `System.IndexOutOfRangeException` is thrown and no further steps are executed. + - The value of character at the offset of the converted index expression with the string `P` becomes the result of the string access. #### 12.8.12.3 Indexer access -For an indexer access, the *primary_expression* of the *element_access* shall be a variable or value of a class, struct, or interface type, and this type shall implement one or more indexers that are applicable with respect to the *argument_list* of the *element_access*. +For an indexer access, the *primary_expression* of the *element_access* shall be a variable or value of a class, struct, or interface type, and this type shall implement one or more indexers that are applicable with respect to the *argument_list* of the *element_access*. The *argument_list* cannot contain `out` or `ref` arguments. The binding-time processing of an indexer access of the form `P[A]`, where `P` is a *primary_expression* of a class, struct, or interface type `T`, and `A` is an *argument_list*, consists of the following steps: @@ -2254,9 +2313,19 @@ The binding-time processing of an indexer access of the form `P[A]`, where `P` i - If `I` is applicable with respect to `A` ([§12.6.4.2](expressions.md#12642-applicable-function-member)) and `S` is a class type other than `object`, all indexers declared in an interface are removed from the set. - If the resulting set of candidate indexers is empty, then no applicable indexers exist, and a binding-time error occurs. - The best indexer of the set of candidate indexers is identified using the overload resolution rules of [§12.6.4](expressions.md#1264-overload-resolution). If a single best indexer cannot be identified, the indexer access is ambiguous, and a binding-time error occurs. -- The index expressions of the *argument_list* are evaluated in order, from left to right. The result of processing the indexer access is an expression classified as an indexer access. The indexer access expression references the indexer determined in the step above, and has an associated instance expression of `P` and an associated argument list of `A`, and an associated type that is the type of the indexer. If `T` is a class type, the associated type is picked from the first declaration or override of the indexer found when starting with `T` and searching through its base classes. +- The accesors of the best indexer are checked: + - If the indexer access is the target of an assignment then the indexer must have a set or ref get accessor, if not a binding-time error occurs; + - Otherwise the indexer must have a get or ref get accesor, if not a binding-time arror occurs. + +The runtime processing of the indexer access consits of the following steps: -Depending on the context in which it is used, an indexer access causes invocation of either the get accessor or the set accessor of the indexer. If the indexer access is the target of an assignment, the set accessor is invoked to assign a new value ([§12.21.2](expressions.md#12212-simple-assignment)). In all other cases, the get accessor is invoked to obtain the current value ([§12.2.2](expressions.md#1222-values-of-expressions)). +- The target *primary_expression* `P` is evaluated. +- The index expressions of the *argument_list* `A` are evaluated in order, from left to right. +- Using the best indexer determined at binding-time: + - If the indexer access is the target of an assignment, the set accessor or ref get accessor is invoked to assign a new value ([§12.21.2](expressions.md#12212-simple-assignment)). + - In all other cases, the get accessor or ref get accesor is invoked to obtain the current value ([§12.2.2](expressions.md#1222-values-of-expressions)). + +The result of processing the indexer access is an expression classified as an indexer access. ### 12.8.13 Null Conditional Element Access @@ -2518,6 +2587,8 @@ An object initializer consists of a sequence of member initializers, enclosed by Each *initializer_target* is followed by an equals sign and either an expression, an object initializer or a collection initializer. It is not possible for expressions within the object initializer to refer to the newly created object it is initializing. +In the *argument_list* of an *initializer_target* there is no implicit support for arguments of type `Index` (§24.4.2) or `Range` (§24.4.3). + A member initializer that specifies an expression after the equals sign is processed in the same way as an assignment ([§12.21.2](expressions.md#12212-simple-assignment)) to the target. A member initializer that specifies an object initializer after the equals sign is a ***nested object initializer***, i.e., an initialization of an embedded object. Instead of assigning a new value to the field or property, the assignments in the nested object initializer are treated as assignments to members of the field or property. Nested object initializers cannot be applied to properties with a value type, or to read-only fields with a value type. @@ -3462,7 +3533,7 @@ An *anonymous_method_expression* is one of two ways of defining an anonymous fun ### 12.9.1 General -The `+`, `-`, `!` (logical negation [§12.9.4](expressions.md#1294-logical-negation-operator) only), `~`, `++`, `--`, cast, and `await` operators are called the unary operators. +The `+`, `-`, `!` (logical negation [§12.9.4](expressions.md#1294-logical-negation-operator) only), `~`, `^`, `++`, `--`, cast, and `await` operators are called the unary operators. > *Note*: The postfix null-forgiving operator ([§12.8.9](expressions.md#1289-null-forgiving-expressions)), `!`, due to its compile-time and non-overloadable only nature, is excluded from the above list. *end note* @@ -3473,6 +3544,7 @@ unary_expression | '-' unary_expression | logical_negation_operator unary_expression | '~' unary_expression + | '^' unary_expression | pre_increment_expression | pre_decrement_expression | cast_expression @@ -3484,7 +3556,12 @@ unary_expression *pointer_indirection_expression* ([§23.6.2](unsafe-code.md#2362-pointer-indirection)) and *addressof_expression* ([§23.6.5](unsafe-code.md#2365-the-address-of-operator)) are available only in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). -If the operand of a *unary_expression* has the compile-time type `dynamic`, it is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). In this case, the compile-time type of the *unary_expression* is `dynamic`, and the resolution described below will take place at run-time using the run-time type of the operand. +If the operand of a *unary_expression* has the compile-time type `dynamic`, it is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). In this case: + +- the compile-time type of the *unary_expression* is: + - `Index` for the `^` hat operator (§hat-operator) + - `dynamic` for all other unary operators; and +- the resolution described below will take place at run-time using the run-time type of the operand. ### 12.9.2 Unary plus operator @@ -3575,6 +3652,26 @@ The result of evaluating `~x`, where `X` is an expression of an enumeration ty Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined bitwise complement operators defined above are also predefined. +### §hat-operator Hat/index from-end operator + +The unary `^` operator is called the *hat* (or *index from-end*) operator. The predefined hat operator is: + +```csharp +Index operator ^(int x); +``` + +The hat operator is not overloadable (§12.4.3). + +The result of an operation of the form `^x` is a from-end `Index` value (§24.2) equivalent to the result of the expression: + +```csharp +new Index(x, true) +``` + +As with the other *unary_expression*s the operand may have a compile-time type of `dynamic` (§12.9.1) and be dynamically bound (§12.3.3). The compile-time type of the result is always `Index`. + +A lifted ([§12.4.8](expressions.md#1248-lifted-operators)) form of the hat operator is also predefined. + ### 12.9.6 Prefix increment and decrement operators ```ANTLR @@ -3706,6 +3803,42 @@ At run-time, the expression `await t` is evaluated as follows: An awaiter’s implementation of the interface methods `INotifyCompletion.OnCompleted` and `ICriticalNotifyCompletion.UnsafeOnCompleted` should cause the delegate `r` to be invoked at most once. Otherwise, the behavior of the enclosing async function is undefined. +## §range-operator Range operator + +The `..` operator is called the *range* operator. + +```ANTLR +range_expression + : unary_expression + | unary_expression? '..' unary_expression? + ; +``` + +The predefined range operator is: + +```csharp +Range operator ..(Index x, Index y); +``` + +The range operator is not overloadable (§12.4.3). + +All range expressions are treated as having the form `x..y`, where: + +- `x` is the left operand if present, otherwise the expression `0`; and +- `y` is the right operand if present, otherwise the expression `^0`. + +The result of the operation is a `Range` value (§24.3) equivalent to the result of the expression: + +```csharp +new Range(x, y) +``` + +If either or both operands in a range expression have the compile-time type `dynamic`, then the expression is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). The compile-time type of the result is always `Range`. + +A lifted ([§12.4.8](expressions.md#1248-lifted-operators)) form of the range operator is also predefined. + +The range operator is non-associative (§12.4.2). + ## 12.10 Arithmetic operators ### 12.10.1 General @@ -3714,10 +3847,10 @@ The `*`, `/`, `%`, `+`, and `-` operators are called the arithmetic operators. ```ANTLR multiplicative_expression - : unary_expression - | multiplicative_expression '*' unary_expression - | multiplicative_expression '/' unary_expression - | multiplicative_expression '%' unary_expression + : range_expression + | multiplicative_expression '*' range_expression + | multiplicative_expression '/' range_expression + | multiplicative_expression '%' range_expression ; additive_expression diff --git a/standard/lexical-structure.md b/standard/lexical-structure.md index 3e466b29c..f440da104 100644 --- a/standard/lexical-structure.md +++ b/standard/lexical-structure.md @@ -1010,11 +1010,11 @@ Punctuators are for grouping and separating. ```ANTLR operator_or_punctuator - : '{' | '}' | '[' | ']' | '(' | ')' | '.' | ',' | ':' | ';' - | '+' | '-' | ASTERISK | SLASH | '%' | '&' | '|' | '^' | '!' | '~' - | '=' | '<' | '>' | '?' | '??' | '::' | '++' | '--' | '&&' | '||' - | '->' | '==' | '!=' | '<=' | '>=' | '+=' | '-=' | '*=' | '/=' | '%=' - | '&=' | '|=' | '^=' | '<<' | '<<=' | '=>' | '??=' + : '{' | '}' | '[' | ']' | '(' | ')' | '.' | ',' | ':' | ';' + | '+' | '-' | '*' | '/' | '%' | '&' | '|' | '^' | '!' | '~' + | '=' | '<' | '>' | '?' | '??' | '::' | '++' | '--' | '&&' | '||' + | '->' | '==' | '!=' | '<=' | '>=' | '+=' | '-=' | '*=' | '/=' | '%=' + | '&=' | '|=' | '^=' | '<<' | '<<=' | '=>' | '??=' | '..' ; right_shift diff --git a/standard/ranges.md b/standard/ranges.md new file mode 100644 index 000000000..af9a61630 --- /dev/null +++ b/standard/ranges.md @@ -0,0 +1,291 @@ +# 24 Extended Indexing and Slicing + +> **Review Note:** This new chapter, currently (§24), is placed here temporarily to avoid text changes due to renumbering occurring in chapters & clauses otherwise unaffected by the PR. It’s final placement is not yet determined, however between the Arrays ([§17](arrays.md#17-arrays)) and Interfaces ([§18](interfaces.md#18-interfaces)) chapters might be suitable – other placements can be suggested during review. It can be relocated later with just a simple edit to `clauses.json`. + +## 24.1 General + +This chapter introduces a model for *extended indexable* and *sliceable* *collection* types built on: + +- The types introduced in this chapter, `System.Index` (§24.2) and `System.Range` (§24.3); +- The pre-defined unary `^` (§hat-operator) and binary `..` (§range-operator) operators; and +- The *element_access* expression. + +Under the model a type is classified as: + +- a *collection* if it represents a group of *element*s +- an *extended indexable* collection if it supports an *element_access* expression which has a single argument expression of type `Index` which returns and/or sets a single element of the type, either by value or by reference; and +- an *extended sliceable* if it supports an *element_access* expression which has a single argument expression of type `Range` which returns a *slice* of the elements of the type by value. + +> *Note*: The model does not require that a slice, unlike an element, of the type can be set, but a type may support it as an extension of the model. *end note* + +The model is supported for single-dimensional arrays (§12.8.12.2) and strings (§string-access). + +The model can be supported by any class, struct or interface type which provides appropriate indexers (§15.9) which implement the model semantics. + +Implicit support for the model is provided for types which do not directly support it but which provide a certain *pattern* of members (§24.4). This support is pattern-based, rather than semantic-based, as the semantics of the type members upon which it is based are *assumed* – the language does not enforce, or check, the semantics of these type members. + +### 24.1.1 Definitions + +For the purposes of this chapter the following terms are defined: + +- A ***collection*** is a type which represents a group of ***element***s +- A ***countable*** collection is one which provides a ***countable property*** an `int` valued instance property whose value is the number of elements currently in the group. This property must be named either `Length` or `Count`, the former is chosen if both exist. +- A ***sequence*** or ***indexable*** type is a collection: + - which is countable; + - where every element can be accessed using an *element_access* expression with a single required `int` argument, the ***from-start index***, additional optional arguments are allowed; + - a sequence is ***modifiable*** if every element can also be set using an *element_access* expression; + - an element’s from-start index is the number of elements before it in the sequence, for a sequence containing *N* elements: + - the first and last elements have indicies of 0 and *N*-1 respectively, and + - the ***past-end*** index, an index which represents a hypothetical element after the last one, has the value *N*; +- A ***from-end index*** represents an element’s position within a sequence relative to the last element. For a sequence containing *N* elements the first, last and past-end indicies are *N*, 1 and 0 respectively. +- A ***range*** is a contiguous run of zero or more indicies starting at any index within a sequence. +- A ***slice*** is the collection of elements within a range. +- A ***sliceable*** collection is one which: + - is countable; + - provides a method `Slice` which takes two `int` parameters specifying a range, being a starting index and a count of elements respectively, and returns a new slice constructed from the elements in the range. + +The above definitions are extended for uses of `Index` and `Range` as follows: + +- A type is also a *sequence* if an *element_access* expression taking a single required `Index` argument, rather than an `int` argument, is supported. Where a distinction is required the type is termed ***extended indexable***. +- A type is also *sliceable* if an *element_access* expression taking a single required `Range` argument, rather a `Slice` method, is supported. Where a distinction is required the type is termed ***extended sliceable***. + +Whether a type is classified as countable, indexable, or sliceable is subject to the constraints of member accessibility (§7.5) and therefore dependent on where the type is being used. + +> *Example*: A type where the countable property and/or the indexer are `protected` is only a sequence to members of itself and any derived types. *end example* + +The required members for a type to qualify as a sequence or sliceable may be inherited. + +> *Example*: In the following code +> +> ```CSharp +> public class A +> { +> public int Length { get { … } } +> } +> +> public class B : A +> { +> public int this(int index) { … } +> } +> +> public class C : B +> { +> public int[] Slice(int index, int count) { … } +> } +> ``` +> +> The type `A` is countable, `B` is a sequence, and `C` is sliceable and a sequence. +> +> *end example* + +*Note*: + +- A type can be sliceable without being indexable due to the lack of an (accessible) indexer. +- For a type to be sliceable and/or indexable requires the type to be countable. +- While the elements of a sequence are ordered by *position* within the sequence the elements themselves need not be ordered by their value, or even orderable. + +*end note* + +## 24.2 The `Index` type + +The `System.Index` type represents an *abstract* index which is either a *from-start index* or a *from-end index*. + +```CSharp + public readonly struct Index : IEquatable + { + public int Value { get; } + public bool IsFromEnd { get; } + + public Index(int value, bool fromEnd = false); + + public static implicit operator Index(int value); + public int GetOffset(int length); + public bool Equals(Index other); + } +``` + +`Index` values are constructed from an `int`, specifying the positive offset, and a `bool`, indicating whether the offset is from the end (`true`) or start (`false`). If the specified offset is negative an `ArgumentOutOfRangeException` is thrown. + +> *Example* +> +> ```CSharp +> Index first = new Index(0, false); // first element index +> var last = new Index(1, true); // last element index +> var past = new Index(0, true); // past-end index +> +> Index invalid = new Index(-1); // throws ArgumentOutOfRangeException +> ``` +> +> *end example* + +There is an implicit conversion from `int` to `Index` which produces from-start indicies, and a language-defined unary operator `^` (§hat-operator) from `int` to `Index` which produces from-end indicies. + +> *Example* +> +> Using implicit conversions and the unary `^` operator the above examples may be written: +> +> ```CSharp +> Index first = 0; // first element index +> var last = ^1; // last element index +> var past = ^0; // past-end index +> ``` +> +> *end example* + +The method `GetOffset` converts from an abstract `Index` value to a concrete `int` index value for a sequence of the specified `length`. + +If the `Index` value, `I`, is from-end this method returns the same value as `length - I.Value`, otherwise it returns the same value as `I.Value`. + +This method does **not** check that the return value is in the valid range of `0` through `length-1` inclusive. + +> *Note:* No checking is specified as the expected use of the result is to index into a sequence with `length` elements, and that indexing operation is expected to perform the appropriate checks. *end note* + +`Index` implements `IEquatable` and values may be compared for equality. However `Index` values are not ordered and no other comparison operations are provided. + +> *Note:* `Index` values are unordered as they are abstract indicies, it is in general impossible to determine whether a from-end index comes before or after a from start index without reference to a sequence length. Once converted to concrete indicies, e.g. by `GetOffset`, those concrete indicies are comparable. *end note* + +`Index` values may be directly used in the *argument_list* of an *element_access* expression (§12.8.12): + +- which is statically bound (§12.3.2) and: + - it is an array access and the target is a single-dimensional array (§12.8.12.2); + - it is a string access (§string-access); or + - it is an indexer access and the target type conforms to a sequence pattern for which implicit `Index` support is specified (§24.4.2). +- which is statically or dynamically bound (§12.3.2) and: + - it is an indexer access and the target type has an indexer with parameters of `Index` type (§12.8.12.3); + +## 24.3 The `Range` type + +The `System.Range` type represents the abstract range of `Index`es from a `Start` index up to, but not including, an `End` index. + +```CSharp + public readonly struct Range : IEquatable + { + public Index Start { get; } + public Index End { get; } + + public Range(Index start, Index end); + + public (int Offset, int Length) GetOffsetAndLength(int length); + public bool Equals(Range other); + } +``` + +`Range` values are constructed from two `Index` values. + +> *Example* +> +> The following examples use the implicit conversion from `int` to `Index` (introduced above) and the `^` (§hat-operator) operator to create the `Index` values for each `Range`: +> +> ```CSharp +> var firstQuad = new Range(0, 4); // the indicies from `0` to `3` +> // int values impicitly convert to `Index` +> var nextQuad = new Range(4, 8); // the indicies from `4` to `7` +> var wholeSeq = new Range(0, ^0); // the indicies from `0` to `N-1` where `N` is the +> // length of the sequence wholeSeq is used with +> var dropFirst = new Range(1, ^0); // the indicies from `1` to `N-1` +> var dropLast = new Range(0, ^1); // the indicies from `0` to `N-2` +> ``` +> +> *end example* + +The language-defined operator `..` (§range-operator) creates a `Range` value from `Index` values. + +> *Example* +> +> Using the `..` the above examples may be written: +> +> ```CSharp +> var firstQuad = 0..4; // the indicies from `0` to `3` +> var nextQuad = 4..8; // the indicies from `4` to `7` +> var wholeSeq = 0..^0; // the indicies from `0` to `N-1` +> var dropFirst = 1..^0; // the indicies from `1` to `N-1` +> var dropLast = 0..^1; // the indicies from `0` to `N-2` +> ``` +> +> *end example* + +The operands of `..` are optional, the first defaults to `0`, the second defaults to `^0`. + +> *Example* +> +> Four of the above examples can also be written: +> +> ```CSharp +> var firstQuad = ..4; // the indicies from `0` to `3` +> var wholeSeq = ..; // the indicies from `0` to `N-1` +> var dropFirst = 1..; // the indicies from `1` to `N-1` +> var dropLast = ..^1; // the indicies from `0` to `N-2` +> ``` +> +> *end example* + +The method `GetOffsetAndLength` converts an abstract `Range` value to a tuple value consisting of a concrete `int` index and a number of elements, applicable to a sequence with `length` elements. If the `Range` value is invalid with respect to sequence with `length` elements this method throws `ArgumentOutOfRangeException`. + +> *Example* +> +> Using the variables defined above with `GetOffSetAndLength(6)`: +> +> ```CSharp +> var (ix0, len0) = firstQuad.GetOffsetAndLength(6); // ix0 = 0, len0 = 4 +> var (ix1, len1) = nextQuad.GetOffsetAndLength(6); // throws ArgumentOutOfRangeException +> // as range crosses sequence end +> var (ix2, len2) = wholeSeq.GetOffsetAndLength(6); // ix2 = 0, len2 = 6 +> var (ix3, len3) = dropFirst.GetOffsetAndLength(6); // ix3 = 1, len3 = 5 +> var (ix4, len4) = dropLast.GetOffsetAndLength(6); // ix4 = 0, len4 = 5 +> ``` + +`Range` implements `IEquatable` and values may be compared for equality. However `Range` values are not ordered and no other comparison operations are provided. + +> *Note:* `Range` values are unordered both as they are abstract and there is no unique ordering relation. Once converted to a concrete start and length, e.g. by `GetOffsetAndLength`, and ordering relation could be defined. *end note* + +`Range` values can be directly used in the *argument_list* of an *element_access* expression (§12.8.12): + +- which is statically bound (§12.3.2) and: + - it is an array access and the target is a single-dimensional array (§12.8.12.2); + - it is a string access (§string-access); or + - it is an indexer access (§12.8.12.3) and the target type conforms to a sequence pattern for which implicit `Range` support is specified (§24.4.3). +- which is statically or dynamically bound (§12.3.2) and: + - it is an indexer access and the target type has an indexer with parameters of `Range` type (§12.8.12.3). + +## 24.4 Pattern-based implicit support for `Index` and `Range` + +### 24.4.1 General + +If a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible at compile-time to `Index` or `Range`; fails to be identified as: + +- an array access (§12.8.12.2), +- a string access (§string-access), or +- or and indexer access (§12.8.12.3) as `T` provides no suitable accessible indexer + +then pattern-based implicit support for the expression is provided if `T` conforms to a pattern. If `T` does not conform to the pattern then a compile-time error occurs. + +### 24.4.2 Implicit `Index` Support + +If in any context a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index`; is not valid (§24.4.1) then if in the same context: + +- `T` provides accessible members qualifying it as a *sequence* (§24.1.1); and +- the expression `E[0]` is valid + +then the expression `E[A]` shall be implicitly supported. + +Without otherwise constraining implementations of this Standard the order of evaluation of the expression shall be equivalent to: + +1. `E` is evaluated; +2. `A` is evaluated; +3. the countable property of `T` is evaluated, if required by the implementation; +4. the get or set accessor of the `int` based indexer of `T` that would be used by `E[0]` in the same context is invoked. + +### 24.4.3 Implicit `Range` Support + +If in any context a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid (§24.4.1) then if in the same context: + +- `T` provides accessible members qualifying it as both *countable* and *sliceable* (§24.1.1) + +then the expression `E[A]` shall be implicitly supported. + +Without otherwise constraining implementations of this Standard the order of evaluation of the expression shall be equivalent to: + +1. `E` is evaluated; +2. `A` is evaluated; +3. the countable property of `T` is evaluated, if required by the implementation; +4. the `Slice` method of `T` is invoked. diff --git a/standard/standard-library.md b/standard/standard-library.md index 9e8efdac0..a3b1aced6 100644 --- a/standard/standard-library.md +++ b/standard/standard-library.md @@ -36,6 +36,12 @@ namespace System public ArgumentException(string? message, Exception? innerException); } + public class ArgumentOutOfRangeException : ArgumentException + { + public ArgumentOutOfRangeException(string? paramName); + public ArgumentOutOfRangeException(string? paramName, string? message); + } + public class ArithmeticException : Exception { public ArithmeticException(); @@ -130,6 +136,11 @@ namespace System void Dispose(); } + public interface IEquatable + { + bool Equals(T? other); + } + public interface IFormattable { } public sealed class IndexOutOfRangeException : Exception @@ -396,6 +407,164 @@ namespace System public OperationCanceledException(string? message, Exception? innerException); } + /// + /// A read-only value type which represents an abstract + /// index to be used with collections. + /// - The Index can be relative to the start or end of a + /// collection. + /// - An Index can be converted to a zero-based concrete + /// from-start index to be used with a collection + /// of some specified length. + /// - Equality between Index values is provided, however + /// unlike concrete indicies they are not ordered. + /// - Array and String element access support indexing + /// with Index values. + /// + public readonly struct Index : IEquatable + { + /// + /// Construct an Index from an integer value and a + /// boolean indicating whether the value is relative + /// to the end (true) or start (false). + /// + /// + /// The value, must be ≥ 0. + /// + /// + /// Optional boolean indicating whether the Index is + /// relative to the end (true) or start (false). + /// The default value is false. + /// + /// + /// Thrown if value < 0. + /// + /// + /// If the Index is relative to the start then: + /// - the value 0 refers to the first element. + /// If the Index is relative to the end then: + /// - the value 1 refers to the last element; and + /// - the value 0 refers to beyond last element. + /// + public Index(int value, bool fromEnd = false); + + /// + /// Implicit conversion from integer to a + /// from-start Index. + /// + /// + /// The predefined operator: + /// Index operator ^(int value); + /// is provided to convert from integer to a + /// from-end Index. + /// + public static implicit operator Index(int value); + + /// + /// Return the value. + /// + public int Value { get; } + + /// + /// Return whether the Index is relative to + /// the end (true) or start (false). + /// + public bool IsFromEnd { get; } + + /// + /// Return a concrete from-start index for a + /// given collection length. + /// + /// + /// The length of the collection that the index + /// will be used with. + /// + /// + /// This method performs no sanity checking and + /// will never throw an IndexOutOfRangeException. + /// It is expected that the returned index will be + /// used with a collection which will do validation. + /// + public int GetOffset(int length); + + /// + /// Indicates whether the current Index value is + /// equal to another Index value. + /// + /// + /// The value to compare with this Index. + /// + public bool Equals(Index other); + } + + /// + /// A read-only value type which represents a range of + /// abstract indicies to be used with collections. + /// - The Range has two Index properties, Start and End. + /// - A Range can be converted to a concrete index from + /// the start and a length value to be used with a + /// collection of some specified length. + /// - Equality between Range values is provided, + /// however they are not ordered. + /// - Array and String element access supports indexing + /// with Range values, returning a sub-array/substring + /// of the indexed value respectively. + /// + public readonly struct Range : IEquatable + { + /// + /// Construct a Range from two Index values. + /// + /// + /// The inclusive Index value for the start + /// of the range. + /// + /// + /// The exclusive Index value for the end + /// of the range. + /// + /// As Index values represent unordered abstract + /// indicies no sanity checking can be performed + /// on the resultant Range value, + /// ". + /// + /// The predefined operator: + /// Range operator ..(Index start, Index end); + /// also exists to create a Range value. + /// + public Range(Index start, Index end); + + /// Return the starting Index. + public Index Start { get; } + + /// Return the ending Index. + public Index End { get; } + + /// + /// Return a concrete from-start index and the + /// range length for a given collection length. + /// + /// + /// The length of the collection that the result + /// will be used with. + /// + /// + /// Thrown if the range is not valid wrt length. + /// + /// + /// A tuple consisting of an index value and range length + /// + public (int Offset, int Length) GetOffsetAndLength(int length); + + /// + /// Indicates whether the current Range value is equal + /// to another Range value. + /// + /// + /// The value to compare with this Range. + /// + public bool Equals(Range other); + } + public readonly ref struct ReadOnlySpan { public int Length { get; } @@ -1105,6 +1274,7 @@ The following library types are referenced in this specification. The full names - `global::System.Action` - `global::System.ArgumentException` +- `global::System.ArgumentOutOfRangeException` - `global::System.ArithmeticException` - `global::System.Array` - `global::System.ArrayTypeMisMatchException` @@ -1124,7 +1294,9 @@ The following library types are referenced in this specification. The full names - `global::System.GC` - `global::System.IAsyncDisposable` - `global::System.IDisposable` +- `global::System.IEquatable` - `global::System.IFormattable` +- `global::System.Index` - `global::System.IndexOutOfRangeException` - `global::System.Int16` - `global::System.Int32` @@ -1140,6 +1312,7 @@ The following library types are referenced in this specification. The full names - `global::System.OperationCanceledException` - `global::System.OutOfMemoryException` - `global::System.OverflowException` +- `global::System.Range` - `global::System.ReadOnlySpan` - `global::System.SByte` - `global::System.Single` diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.gruntree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.gruntree.red.txt index 2b6bc6914..1f0eb4e20 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.gruntree.red.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.gruntree.red.txt @@ -598,7 +598,7 @@ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ * ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ -⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ number diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.tree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.tree.red.txt index b2451249c..0faf8849b 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.tree.red.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.tree.red.txt @@ -1 +1 @@ -(prog (compilation_unit (namespace_declaration namespace (qualified_identifier (identifier My)) (namespace_body { (namespace_member_declaration (enum_declaration (attributes (attribute_section [ (attribute_target_specifier (attribute_target (identifier type)) :) (attribute_list (identifier Flags)) ])) (enum_modifier public) enum (identifier E) (enum_body { (enum_member_declarations (enum_member_declaration (identifier A)) , (enum_member_declaration (identifier B) = (constant_expression (identifier A))) , (enum_member_declaration (identifier C) = (constant_expression (additive_expression (additive_expression (literal 2)) + (multiplicative_expression (identifier A))))) , (enum_member_declaration (identifier D))) , }))) (namespace_member_declaration (delegate_declaration (delegate_modifier public) delegate (return_type void) (delegate_header (identifier Delegate) ( (parameter_list (fixed_parameter (type (class_type object)) (identifier P))) ) ;))) (namespace_member_declaration (namespace_declaration namespace (qualified_identifier (identifier Test)) (namespace_body { (using_directive (using_namespace_directive using (namespace_name (identifier System)) ;)) (using_directive (using_namespace_directive using (namespace_name (namespace_or_type_name (identifier System) . (identifier Collections))) ;)) (namespace_member_declaration (class_declaration (class_modifier public) class (identifier Список) (class_body { (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) (method_modifier (ref_method_modifier static))) (return_type (identifier IEnumerable)) (method_header (member_name (identifier Power)) ( (parameter_list (fixed_parameters (fixed_parameter (type (integral_type int)) (identifier number)) , (fixed_parameter (type (integral_type int)) (identifier exponent)))) )) (method_body (block { (statement_list (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (identifier Список)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier Список) = (local_variable_initializer (object_creation_expression new (type (identifier Список)) ( ))))))) ;)) (statement (expression_statement (statement_expression (invocation_expression (primary_expression (member_access (primary_expression (identifier Список)) . (identifier Main))) ( ))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier counter) = (local_variable_initializer (parenthesized_expression ( (expression (additive_expression (additive_expression (literal 0)) + (multiplicative_expression (literal 0)))) ))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier אתר) = (local_variable_initializer (literal 0)))))) ;)) (statement (while_statement while ( (boolean_expression (relational_expression (relational_expression (pre_increment_expression ++ (unary_expression (post_increment_expression (primary_expression (identifier counter)) ++)))) < (shift_expression (pre_decrement_expression -- (unary_expression (post_decrement_expression (primary_expression (identifier exponent)) --)))))) ) (embedded_statement (block { (statement_list (statement (expression_statement (statement_expression (assignment (unary_expression (identifier result)) (assignment_operator =) (expression (additive_expression (additive_expression (additive_expression (multiplicative_expression (multiplicative_expression (identifier result)) * (unary_expression (identifier number)))) + (multiplicative_expression (unary_expression + (unary_expression (post_increment_expression (primary_expression (post_increment_expression (primary_expression (identifier number)) ++)) ++))))) + (multiplicative_expression (identifier number)))))) ;)) (statement (yield_statement yield return (expression (identifier result)) ;))) }))))) })))) (class_member_declaration (method_declaration (method_modifiers (ref_method_modifier static)) (return_type void) (method_header (member_name (identifier Main)) ( )) (method_body (block { (statement_list (foreach_statement foreach ( (local_variable_type (integral_type int)) (identifier i) in (expression (invocation_expression (primary_expression (identifier Power)) ( (argument_list (argument (literal 2)) , (argument (literal 8))) ))) ) (embedded_statement (block { (statement_list (expression_statement (statement_expression (invocation_expression (primary_expression (member_access (primary_expression (identifier Console)) . (identifier Write))) ( (argument_list (argument (literal "{0} ")) , (argument (identifier i))) ))) ;)) })))) })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier async)) (return_type void) (method_header (member_name (identifier Wait)) ( )) (method_body (block { (statement_list (expression_statement (statement_expression (await_expression await (unary_expression (invocation_expression (primary_expression (member_access (primary_expression (member_access (primary_expression (member_access (primary_expression (member_access (primary_expression (identifier System)) . (identifier Threading))) . (identifier Tasks))) . (identifier Task))) . (identifier Delay))) ( (argument_list (literal 0)) ))))) ;)) })))) (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier AsyncAnonymous)) ( )) (method_body (block { (statement_list (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier task) = (expression (invocation_expression (primary_expression (member_access (primary_expression (member_access (primary_expression (identifier Task)) . (identifier Factory))) . (identifier StartNew))) ( (argument_list (lambda_expression async (anonymous_function_signature (explicit_anonymous_function_signature ( ))) => (anonymous_function_body (block { (statement_list (return_statement return (expression (await_expression await (unary_expression (invocation_expression (primary_expression (member_access (primary_expression (object_creation_expression new (type (identifier WebClient)) ( ))) . (identifier DownloadStringTaskAsync))) ( (argument_list (literal "http://example.com")) ))))) ;)) })))) )))))) ;)) })))) }))) }))) })))) +(prog (compilation_unit (namespace_declaration namespace (qualified_identifier (identifier My)) (namespace_body { (namespace_member_declaration (enum_declaration (attributes (attribute_section [ (attribute_target_specifier (attribute_target (identifier type)) :) (attribute_list (identifier Flags)) ])) (enum_modifier public) enum (identifier E) (enum_body { (enum_member_declarations (enum_member_declaration (identifier A)) , (enum_member_declaration (identifier B) = (constant_expression (identifier A))) , (enum_member_declaration (identifier C) = (constant_expression (additive_expression (additive_expression (literal 2)) + (multiplicative_expression (identifier A))))) , (enum_member_declaration (identifier D))) , }))) (namespace_member_declaration (delegate_declaration (delegate_modifier public) delegate (return_type void) (delegate_header (identifier Delegate) ( (parameter_list (fixed_parameter (type (class_type object)) (identifier P))) ) ;))) (namespace_member_declaration (namespace_declaration namespace (qualified_identifier (identifier Test)) (namespace_body { (using_directive (using_namespace_directive using (namespace_name (identifier System)) ;)) (using_directive (using_namespace_directive using (namespace_name (namespace_or_type_name (identifier System) . (identifier Collections))) ;)) (namespace_member_declaration (class_declaration (class_modifier public) class (identifier Список) (class_body { (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) (method_modifier (ref_method_modifier static))) (return_type (identifier IEnumerable)) (method_header (member_name (identifier Power)) ( (parameter_list (fixed_parameters (fixed_parameter (type (integral_type int)) (identifier number)) , (fixed_parameter (type (integral_type int)) (identifier exponent)))) )) (method_body (block { (statement_list (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (identifier Список)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier Список) = (local_variable_initializer (object_creation_expression new (type (identifier Список)) ( ))))))) ;)) (statement (expression_statement (statement_expression (invocation_expression (primary_expression (member_access (primary_expression (identifier Список)) . (identifier Main))) ( ))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier counter) = (local_variable_initializer (parenthesized_expression ( (expression (additive_expression (additive_expression (literal 0)) + (multiplicative_expression (literal 0)))) ))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier אתר) = (local_variable_initializer (literal 0)))))) ;)) (statement (while_statement while ( (boolean_expression (relational_expression (relational_expression (pre_increment_expression ++ (unary_expression (post_increment_expression (primary_expression (identifier counter)) ++)))) < (shift_expression (pre_decrement_expression -- (unary_expression (post_decrement_expression (primary_expression (identifier exponent)) --)))))) ) (embedded_statement (block { (statement_list (statement (expression_statement (statement_expression (assignment (unary_expression (identifier result)) (assignment_operator =) (expression (additive_expression (additive_expression (additive_expression (multiplicative_expression (multiplicative_expression (identifier result)) * (range_expression (identifier number)))) + (multiplicative_expression (unary_expression + (unary_expression (post_increment_expression (primary_expression (post_increment_expression (primary_expression (identifier number)) ++)) ++))))) + (multiplicative_expression (identifier number)))))) ;)) (statement (yield_statement yield return (expression (identifier result)) ;))) }))))) })))) (class_member_declaration (method_declaration (method_modifiers (ref_method_modifier static)) (return_type void) (method_header (member_name (identifier Main)) ( )) (method_body (block { (statement_list (foreach_statement foreach ( (local_variable_type (integral_type int)) (identifier i) in (expression (invocation_expression (primary_expression (identifier Power)) ( (argument_list (argument (literal 2)) , (argument (literal 8))) ))) ) (embedded_statement (block { (statement_list (expression_statement (statement_expression (invocation_expression (primary_expression (member_access (primary_expression (identifier Console)) . (identifier Write))) ( (argument_list (argument (literal "{0} ")) , (argument (identifier i))) ))) ;)) })))) })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier async)) (return_type void) (method_header (member_name (identifier Wait)) ( )) (method_body (block { (statement_list (expression_statement (statement_expression (await_expression await (unary_expression (invocation_expression (primary_expression (member_access (primary_expression (member_access (primary_expression (member_access (primary_expression (member_access (primary_expression (identifier System)) . (identifier Threading))) . (identifier Tasks))) . (identifier Task))) . (identifier Delay))) ( (argument_list (literal 0)) ))))) ;)) })))) (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier AsyncAnonymous)) ( )) (method_body (block { (statement_list (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier task) = (expression (invocation_expression (primary_expression (member_access (primary_expression (member_access (primary_expression (identifier Task)) . (identifier Factory))) . (identifier StartNew))) ( (argument_list (lambda_expression async (anonymous_function_signature (explicit_anonymous_function_signature ( ))) => (anonymous_function_body (block { (statement_list (return_statement return (expression (await_expression await (unary_expression (invocation_expression (primary_expression (member_access (primary_expression (object_creation_expression new (type (identifier WebClient)) ( ))) . (identifier DownloadStringTaskAsync))) ( (argument_list (literal "http://example.com")) ))))) ;)) })))) )))))) ;)) })))) }))) }))) })))) diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.tree.svg b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.tree.svg index 994d268a4..bc4e09f5e 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.tree.svg +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-I/Reference/sample.tree.svg @@ -515,2076 +515,2076 @@ - - -block - - - -delegate_header - - - -explicitly_typed_local_variable_declaration - - - -+ - - - -primary_expression + + +int - - -0 + + +. - - -expression + + +) - - -primary_expression + + +} - - -ref_method_modifier + + +) - - -Factory + + +explicitly_typed_local_variable_declarator - - -{ + + +argument_list - - -Main + + +System - - + + ; - - -Список - - - -delegate_declaration + + +identifier - - -additive_expression + + +Test - - + + declaration_statement - - -identifier + + +void - - -prog + + +object_creation_expression - - -statement_list + + +System - - -identifier + + +method_declaration - - -{ + + +public - - -statement + + ++ - - -async + + +* - - -await + + +primary_expression - - -; + + +primary_expression - - -A + + +member_access - - -identifier + + +local_variable_initializer - - -identifier + + +argument_list - - -, + + +statement_expression - - + + identifier - - -type - - - -attribute_list - - - -+ + + +statement - - -unary_expression + + +literal - - -identifier + + +argument_list - - + + type - - -) - - - + + identifier - - -namespace_name + + +enum_modifier - - -local_variable_declaration + + +constant_expression - - + + method_body - - -class_type - - - -identifier - - - -return_type - - - -invocation_expression - - - -} + + +method_modifiers - - -method_declaration + + +; P - - -method_header - - - -attribute_target_specifier + + +explicitly_typed_local_variable_declarators - - -Wait + + +unary_expression - - -primary_expression + + +. - - -; + + +class_member_declaration - - -expression + + +block - - -literal + + +public - - -; + + +member_access - - -Collections + + +identifier - - -literal + + +local_variable_declaration - - -explicitly_typed_local_variable_declarators + + +type - - -return_type + + +identifier - - -delegate + + +invocation_expression + + + +assignment + + + +member_name + + + +identifier + + + +argument + + + +identifier + + + +C + + + +, + + + +. + + + +ref_method_modifier + + + +class_type + + + +Список + + + +identifier parameter_list - - -expression_statement + + +explicitly_typed_local_variable_declarators - - -System + + +method_body - - -) + + +attribute_target - - + + +fixed_parameter + + + +literal + + + +await_expression + + + +class_member_declaration + + + block - - -identifier + + +0 - - -identifier + + +multiplicative_expression - - -class_modifier + + +public - - -method_modifiers + + +in - - -) + + +A - - -. + + +Tasks - - -< + + +statement - - -pre_increment_expression + + +local_variable_initializer - - -) + + +namespace_member_declaration - - -boolean_expression + + +argument - - -block + + +fixed_parameters - - + + +=> + + + +static + + + +statement_list + + + +identifier + + + primary_expression - - -type + + +int - - -foreach_statement + + +; - - -method_declaration + + +argument - - -method_declaration + + +delegate_modifier - - -return_statement + + +method_modifiers - - -invocation_expression + + +block - - -invocation_expression + + +namespace_declaration - - -} + + +statement_expression - - -using_directive + + +identifier - - -primary_expression + + +local_variable_initializer - - -namespace_body + + +identifier + + + +declaration_statement + + + +++ + + + +multiplicative_expression + + + +await + + + +( + + + +statement_list + + + +expression + + + +, method_modifier - - -Main + + +attribute_section - - -class_member_declaration + + +qualified_identifier - - -( + + +++ - - -identifier + + +) - - -identifier + + +namespace_body - - -additive_expression + + +pre_increment_expression - - -block + + +. - - -parenthesized_expression + + +Delegate - - -) + + +delegate - - -method_header + + +identifier + + + +qualified_identifier { - - -literal - - - -embedded_statement - - - -local_variable_declaration + + +Console - - + + identifier - - -statement + + +method_body - - -primary_expression + + +Task - - -. + + +int - - -public + + +class_declaration - - -primary_expression + + +expression_statement - - -primary_expression + + += - - -local_variable_type + + +class_member_declaration - - -namespace + + +identifier - - -} + + +additive_expression - - -method_modifier + + +( - - -identifier + + +expression_statement - - -embedded_statement + + +( - - + + +attribute_target_specifier + + + ref_method_modifier - - -unary_expression + + +using_namespace_directive - - -enum_member_declaration + + +result - - -) + + +argument_list - - -static + + +member_name - - + + type - - -post_increment_expression - - - -; + + +additive_expression - - -pre_decrement_expression + + +identifier - - -type + + +embedded_statement - - -+ + + +expression_statement - - -0 + + +invocation_expression - - -method_modifiers + + +method_modifier - - -namespace_or_type_name + + +A - - -, + + +} - - -identifier + + +boolean_expression - - -number + + +result - - -statement_list + + +int - - + + identifier - - -statement - - - -) + + +0 - - -member_access + + +{ - - -+ + + +"{0}·" - - -explicitly_typed_local_variable_declarator + + +additive_expression - - -multiplicative_expression + + +number - - -method_body + + +} - - -fixed_parameter + + +E - - -Delay + + +explicitly_typed_local_variable_declarators - - -identifier + + +{ - - -implicitly_typed_local_variable_declarator + + +explicitly_typed_local_variable_declaration - - -enum_member_declarations + + +, - - -assignment + + +return_type - - + + primary_expression - - + + identifier - - -namespace_body - - - -block - - - -method_header - - - -using_directive - - - + + enum_member_declaration - - -void + + +method_modifier - - -local_variable_initializer + + +shift_expression - - -D + + +expression_statement - - + + identifier - - -) - - - -int + + +exponent - - -statement_expression + + +identifier - - -type + + +2 - - + + ( - - -System + + +primary_expression - - -namespace_declaration + + +identifier - - + + integral_type - - -declaration_statement + + +identifier - - -primary_expression + + +8 - - -local_variable_declaration + + +pre_decrement_expression - - -explicitly_typed_local_variable_declarators + + +2 - - -argument + + +anonymous_function_body - - + + +, + + + ( - - -argument + + +statement_list - - -using_namespace_directive + + +yield_statement - - -integral_type + + +expression - - -exponent + + +"http://example.com" - - -unary_expression + + +statement_list - - -result + + +additive_expression - - -primary_expression + + +counter - - -( + + +relational_expression - - -IEnumerable + + +) - - -Console + + +0 - - -} + + +{ - - -identifier + + +explicit_anonymous_function_signature - - -number + + +identifier - - -A + + +( - - -} + + +identifier - - -) + + +await - - -; + + +type - - -foreach + + +declaration_statement - - -explicitly_typed_local_variable_declaration + + +type - - -{ + + +++ - - -identifier + + +number - - -expression_statement + + +using_directive - - + + primary_expression - - -A + + +unary_expression - - -) + + +method_declaration - - + + identifier - - -expression_statement + + +return_type + + + +member_name + + + +, + + + +; + + + +( - - -class + + +member_name - - -new + + +; - - -( + + +literal - - -result + + +void - - + + identifier - - -( + + +; - - + + +argument_list + + + identifier - - -literal + + +invocation_expression { - - -integral_type - - - -int + + +{ - - -namespace_member_declaration + + +. - - -i + + +invocation_expression - - -expression + + +multiplicative_expression - - -) + + +Main - - -literal + + +anonymous_function_signature - - + + identifier - - -compilation_unit + + +( - - -= + + +await_expression - - -statement + + +( - - -integral_type + + += - - -unary_expression + + +expression - - -[ + + +method_header - - -counter + + +statement_expression - - -2 + + +compilation_unit - - -. + + +namespace_member_declaration - - -enum_modifier + + +primary_expression - - -) + + +namespace_name - - -0 + + +identifier - - -StartNew + + +range_expression - - -( + + +using - - -enum_declaration + + +) - - -explicitly_typed_local_variable_declarators + + +while_statement - - -literal + + +DownloadStringTaskAsync - - -multiplicative_expression + + += - - -class_member_declaration + + +block - - -} + + +System - - -method_body + + +) - - --- + + +) - - -method_declaration + + +( - - + + = - - -, - - - -member_access - - - -. - - - -argument_list - - - -post_increment_expression + + +return_statement - - -async + + +literal - - -class_member_declaration + + +embedded_statement - - + + return_type - - -identifier + + +method_declaration - - -Tasks + + +primary_expression - - -Task + + +IEnumerable - - -Threading + + +local_variable_declaration - - -enum + + +additive_expression - - -explicitly_typed_local_variable_declaration + + +{ - - -enum_member_declaration + + +namespace - - -) + + +literal - - + + identifier - - -{ - - - -invocation_expression - - - -statement_list + + +local_variable_declaration - - -statement_expression + + +int - - -local_variable_initializer + + +primary_expression - - -exponent + + +A - - -public + + +-- - - -member_access + + +attributes - - -multiplicative_expression + + +namespace_or_type_name - - -qualified_identifier + + +result - - -invocation_expression + + +explicitly_typed_local_variable_declaration - - -fixed_parameters + + +primary_expression - - -var + + +statement - - -literal + + +parenthesized_expression - - -void + + +i - - -await_expression + + +{ - - -statement_list + + +fixed_parameter - - -} + + +new B - - -, - - - -local_variable_declaration - - - -. - - - -statement_list - - - -qualified_identifier + + +Delay - - -int + + +; - - -declaration_statement + + +member_access - - --- + + +primary_expression - - -class_body + + +statement - - -identifier + + +. - - -expression + + +( - - -E + + +member_access - - -identifier + + +new - - -namespace_member_declaration + + +literal - - -identifier + + ++ + + + +multiplicative_expression post_increment_expression - - -Power + + +identifier - - -task + + +local_variable_type - - -identifier + + +using - - -{ + + +implicitly_typed_local_variable_declaration - - -= + + +parameter_list - - -result + + +enum - - -2 + + +explicitly_typed_local_variable_declaration - - -( + + +method_header - - -expression_statement + + +var - - -void + + +async - - -) + + +namespace_body - - -member_access + + +; - - -( + + +object_creation_expression - - -anonymous_function_body + + +identifier - - -fixed_parameter + + +enum_member_declaration - - -multiplicative_expression + + +-- - - -( + + +) - - + + +} + + + identifier - - -void + + +( - - -explicitly_typed_local_variable_declarator + + +statement_list - - -additive_expression + + +( - - -identifier + + +Список - - -anonymous_function_signature + + +class_body - - -method_modifier + + +Список - - -object + + +unary_expression - - -] + + +number - - -statement + + +constant_expression - - + + +integral_type + + + +primary_expression + + + ( - - -number + + +primary_expression - - -argument + + +. - - -literal + + +lambda_expression - - -unary_expression + + +return - - -delegate_modifier + + +member_access - - -identifier + + +integral_type - - -explicitly_typed_local_variable_declarator + + +type - - + + identifier - - -attributes - - - -declaration_statement + + +identifier type - - -{ - - - -method_body - - - -{ - - - -argument_list - - - -identifier + + +namespace_member_declaration - - -; + + +integral_type - - -constant_expression + + +namespace_declaration - - -argument + + +Power - - -i + + +implicitly_typed_local_variable_declarator - - -enum_member_declaration + + +foreach - - -= + + +StartNew - - -argument_list + + +D - - -; + + +Power - - -identifier + + +Main - - -await_expression + + +literal - - -class_member_declaration + + +; - - -Delegate + + +statement - - + + identifier - - -C - - - -My + + +multiplicative_expression - - -object_creation_expression + + +async - - + + identifier - - -static + + +statement_list - - -, + + +identifier - - -0 + + +using_directive - - -expression + + +} - - -literal + + +Write - - -statement_expression + + +method_declaration - - -attribute_section + + +fixed_parameter - - -"{0}·" + + +Список - - -) + + +explicitly_typed_local_variable_declarator - - -primary_expression + + +post_increment_expression - - -using + + +type - - + + member_access - - -Список + + +method_modifiers - - + + identifier - - -. + + +enum_member_declarations - - -enum_body + + +: - - -Список + + +. ( - - + + +identifier + + + ++ - - -( + + +identifier - - -member_access + + +block - - -primary_expression + + +Threading אתר - - -int - - - -shift_expression + + +{ - - -++ + + +void - - -. + + +identifier - - -( + + +invocation_expression - - -await + + +static - - -statement + + +primary_expression - - -= + + +Flags - - -: + + +unary_expression - - -using_namespace_directive + + +; - - + + identifier - - -=> - - - + + ) - - -} - - - -fixed_parameter - - - -in + + +) - - -primary_expression + + +prog - - -namespace_member_declaration + + +; - - -relational_expression + + +) - - -++ + + +block - - -number + + +declaration_statement - - -object_creation_expression + + +exponent - - -"http://example.com" + + +literal - - -implicitly_typed_local_variable_declaration + + +unary_expression - - -member_access + + +, - - -while_statement + + +block - - + + identifier - - -return + + +enum_declaration - - -++ + + +primary_expression - - -identifier + + +{ counter - - -method_modifiers - - - -member_name + + +0 - - -namespace_name + + +< - - -yield + + +member_access - - -attribute_target + + +identifier - - -* + + +WebClient - - -int + + +argument - - -= + + +; - - -{ + + +foreach_statement - - -post_decrement_expression + + +statement - - -invocation_expression + + +AsyncAnonymous - - -; + + +. - - -, + + +member_access - - + + identifier - - -argument_list - - - -statement_expression - - - -( - - - -namespace_member_declaration + + ++ - - -new + + ++ - - + + identifier - - -Write + + +expression - - -} + + += + + + +Список - - -unary_expression + + +return - - -unary_expression + + +yield - - -Power + + +[ - - -return_type + + +enum_member_declaration - - -Task + + +return_type - - -; + + +using_namespace_directive - - -ref_method_modifier + + +post_decrement_expression - - -method_header + + +) - - -member_name + + +integral_type - - -, + + +delegate_declaration - - -Test + + +] while - - -integral_type + + +} - - -local_variable_initializer + + +) - - -public + + +attribute_list - - -unary_expression + + +primary_expression - - -identifier + + +method_header - - -additive_expression + + +namespace_name - - -AsyncAnonymous + + +Wait - - -statement_list + + +public - - -primary_expression + + +. - - -return + + +delegate_header - - -class_declaration + + +identifier - - -member_access + + +Factory - - + + identifier - - -block - - - -method_modifiers + + +identifier - - -yield_statement + + +} } - - -multiplicative_expression - - - -identifier - - - -( - - - -Список - - - -relational_expression + + +primary_expression - - -DownloadStringTaskAsync + + +) - - -; + + +) - - -WebClient + + +void - - -System + + +enum_body - - -parameter_list + + +unary_expression - - + + primary_expression - - -return_type - - - -+ - - - -statement + + +identifier - - -member_name + + +member_access - - -constant_expression + + +number - - -identifier + + +class_modifier - - -. + + +post_increment_expression - - -explicit_anonymous_function_signature + + +My - - -namespace_declaration + + +Task - - -assignment_operator + + +unary_expression - - -type + + +i - - -argument_list + + +class - - -; + + +invocation_expression - - -identifier + + +object - - -block + + +class_member_declaration additive_expression - - + + +return_type + + + +expression + + + identifier - - -{ + + += - - -; + + +) - - -public + + +relational_expression - - -type + + +multiplicative_expression - - -member_name + + +primary_expression - - -using + + +literal - - -Flags + + +, - - -identifier + + +ref_method_modifier - - -8 + + +} - - + + +expression + + + +additive_expression + + + +; + + + +method_header + + + identifier - - -expression + + +type - - -= + + +explicitly_typed_local_variable_declarator - - + + identifier - - -multiplicative_expression + + +} - - + + ) - - -Список + + +local_variable_declaration - - -member_access + + +method_modifiers - - -additive_expression + + +statement - - -primary_expression + + += - - -additive_expression + + +} - - -lambda_expression + + +identifier + + + +enum_member_declaration + + + +{ + + + ++ + + + +task namespace - - -} - - - -. + + +statement_expression - - + + identifier - - -. + + +statement_list - - -primary_expression + + +method_body - - + + ( - - -statement_list + + +namespace_member_declaration + + + +( + + + +assignment_operator + + + +Collections \ No newline at end of file diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.gruntree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.gruntree.red.txt index 318651ca2..0478900c7 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.gruntree.red.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.gruntree.red.txt @@ -845,7 +845,7 @@ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ * ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ -⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ i @@ -854,7 +854,7 @@ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ / ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ -⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ i @@ -863,7 +863,7 @@ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ % ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ -⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ i diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.red.txt index 0b336426c..4dcda1537 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.red.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.red.txt @@ -1 +1 @@ -(prog (compilation_unit (namespace_declaration namespace (qualified_identifier (identifier Comments) . (identifier XmlComments) . (identifier UndocumentedKeywords)) (namespace_body { (namespace_member_declaration (class_declaration class (identifier (contextual_keyword yield)) (class_body { (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier Params)) ( (parameter_list (fixed_parameters (fixed_parameter (parameter_modifier (parameter_mode_modifier ref)) (type (contextual_keyword dynamic)) (identifier a)) , (fixed_parameter (parameter_modifier (parameter_mode_modifier out)) (type (contextual_keyword dynamic)) (identifier b))) , (parameter_array params (array_type (non_array_type (contextual_keyword dynamic)) (rank_specifier [ ])) (identifier c))) )) (method_body (block { })))) (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier Params)) ( (parameter_list (fixed_parameters (fixed_parameter (parameter_modifier (parameter_mode_modifier out)) (type (contextual_keyword dynamic)) (identifier a) (default_argument = (expression (literal 2)))) , (fixed_parameter (parameter_modifier (parameter_mode_modifier ref)) (type (contextual_keyword dynamic)) (identifier c) (default_argument = (expression (explictly_typed_default default ( (type (contextual_keyword dynamic)) )))))) , (parameter_array params (array_type (non_array_type (contextual_keyword dynamic)) (rank_specifier [ ]) (rank_specifier [ ])) (identifier c))) )) (method_body (block { })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) (method_modifier (ref_method_modifier override))) (return_type (class_type string)) (method_header (member_name (identifier ToString)) ( )) (method_body (block { (statement_list (return_statement return (expression (invocation_expression (primary_expression (base_access base . (identifier ToString))) ( ))) ;)) })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) partial) (return_type void) (method_header (member_name (identifier OnError)) ( )) (method_body ;))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) partial) (return_type void) (method_header (member_name (identifier method)) ( )) (method_body (block { (statement_list (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (array_type (non_array_type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) (rank_specifier [ ]))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier a) = (local_variable_initializer (array_creation_expression new (non_array_type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) [ (expression_list (literal 5)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (array_type (non_array_type (integral_type int)) (rank_specifier [ ]))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier (contextual_keyword var)) = (local_variable_initializer (array_initializer { (variable_initializer_list (variable_initializer (literal 1)) , (variable_initializer (literal 2)) , (variable_initializer (literal 3)) , (variable_initializer (literal 4)) , (variable_initializer (literal 5))) })))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier i) = (local_variable_initializer (element_access (primary_expression (identifier a)) [ (argument_list (identifier i)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (namespace_or_type_name (identifier Foo) (type_argument_list < (type_argument (identifier T)) >))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier f) = (local_variable_initializer (object_creation_expression new (type (namespace_or_type_name (identifier Foo) (type_argument_list < (type_argument (integral_type int)) >))) ( ))))))) ;)) (statement (expression_statement (statement_expression (invocation_expression (primary_expression (member_access (primary_expression (identifier f)) . (identifier method))) ( ))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier i)) (assignment_operator =) (expression (inclusive_or_expression (inclusive_or_expression (and_expression (and_expression (additive_expression (additive_expression (additive_expression (identifier i)) + (multiplicative_expression (identifier i))) - (multiplicative_expression (multiplicative_expression (multiplicative_expression (multiplicative_expression (identifier i)) * (unary_expression (identifier i))) / (unary_expression (identifier i))) % (unary_expression (identifier i))))) & (equality_expression (identifier i)))) | (exclusive_or_expression (exclusive_or_expression (identifier i)) ^ (and_expression (identifier i))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (simple_type bool)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier b) = (local_variable_initializer (inclusive_or_expression (inclusive_or_expression (and_expression (and_expression (boolean_literal true)) & (equality_expression (boolean_literal false)))) | (exclusive_or_expression (exclusive_or_expression (boolean_literal true)) ^ (and_expression (boolean_literal false))))))))) ;))) })))) }))) })))) +(prog (compilation_unit (namespace_declaration namespace (qualified_identifier (identifier Comments) . (identifier XmlComments) . (identifier UndocumentedKeywords)) (namespace_body { (namespace_member_declaration (class_declaration class (identifier (contextual_keyword yield)) (class_body { (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier Params)) ( (parameter_list (fixed_parameters (fixed_parameter (parameter_modifier (parameter_mode_modifier ref)) (type (contextual_keyword dynamic)) (identifier a)) , (fixed_parameter (parameter_modifier (parameter_mode_modifier out)) (type (contextual_keyword dynamic)) (identifier b))) , (parameter_array params (array_type (non_array_type (contextual_keyword dynamic)) (rank_specifier [ ])) (identifier c))) )) (method_body (block { })))) (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier Params)) ( (parameter_list (fixed_parameters (fixed_parameter (parameter_modifier (parameter_mode_modifier out)) (type (contextual_keyword dynamic)) (identifier a) (default_argument = (expression (literal 2)))) , (fixed_parameter (parameter_modifier (parameter_mode_modifier ref)) (type (contextual_keyword dynamic)) (identifier c) (default_argument = (expression (explictly_typed_default default ( (type (contextual_keyword dynamic)) )))))) , (parameter_array params (array_type (non_array_type (contextual_keyword dynamic)) (rank_specifier [ ]) (rank_specifier [ ])) (identifier c))) )) (method_body (block { })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) (method_modifier (ref_method_modifier override))) (return_type (class_type string)) (method_header (member_name (identifier ToString)) ( )) (method_body (block { (statement_list (return_statement return (expression (invocation_expression (primary_expression (base_access base . (identifier ToString))) ( ))) ;)) })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) partial) (return_type void) (method_header (member_name (identifier OnError)) ( )) (method_body ;))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) partial) (return_type void) (method_header (member_name (identifier method)) ( )) (method_body (block { (statement_list (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (array_type (non_array_type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) (rank_specifier [ ]))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier a) = (local_variable_initializer (array_creation_expression new (non_array_type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) [ (expression_list (literal 5)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (array_type (non_array_type (integral_type int)) (rank_specifier [ ]))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier (contextual_keyword var)) = (local_variable_initializer (array_initializer { (variable_initializer_list (variable_initializer (literal 1)) , (variable_initializer (literal 2)) , (variable_initializer (literal 3)) , (variable_initializer (literal 4)) , (variable_initializer (literal 5))) })))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier i) = (local_variable_initializer (element_access (primary_expression (identifier a)) [ (argument_list (identifier i)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (namespace_or_type_name (identifier Foo) (type_argument_list < (type_argument (identifier T)) >))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier f) = (local_variable_initializer (object_creation_expression new (type (namespace_or_type_name (identifier Foo) (type_argument_list < (type_argument (integral_type int)) >))) ( ))))))) ;)) (statement (expression_statement (statement_expression (invocation_expression (primary_expression (member_access (primary_expression (identifier f)) . (identifier method))) ( ))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier i)) (assignment_operator =) (expression (inclusive_or_expression (inclusive_or_expression (and_expression (and_expression (additive_expression (additive_expression (additive_expression (identifier i)) + (multiplicative_expression (identifier i))) - (multiplicative_expression (multiplicative_expression (multiplicative_expression (multiplicative_expression (identifier i)) * (range_expression (identifier i))) / (range_expression (identifier i))) % (range_expression (identifier i))))) & (equality_expression (identifier i)))) | (exclusive_or_expression (exclusive_or_expression (identifier i)) ^ (and_expression (identifier i))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (simple_type bool)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier b) = (local_variable_initializer (inclusive_or_expression (inclusive_or_expression (and_expression (and_expression (boolean_literal true)) & (equality_expression (boolean_literal false)))) | (exclusive_or_expression (exclusive_or_expression (boolean_literal true)) ^ (and_expression (boolean_literal false))))))))) ;))) })))) }))) })))) diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.svg b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.svg index 515bf538c..febbbbcfa 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.svg +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.svg @@ -451,1820 +451,1820 @@ - - -rank_specifier + + +type_argument - - + + +class_member_declaration + + + +) + + + identifier - - -3 + + +UndocumentedKeywords - - -exclusive_or_expression + + +array_initializer + + + +inclusive_or_expression + + + +( + + + +type + + + +parameter_modifier array_type - - -explicitly_typed_local_variable_declarators + + +type_argument - - -identifier + + +] - - -; + + +class_type - - -exclusive_or_expression + + +multiplicative_expression - - + + identifier - - -method + + +method_body - - -unary_expression + + += - - -identifier + + +; - - -expression_statement + + +integral_type - - -Params + + +b - - -member_name + + +new - - -nullable_value_type + + +( - - -type + + +parameter_list - - -override + + +multiplicative_expression - - -member_access + + +type - - -out + + +type - - -] + + +method - - -local_variable_declaration + + +identifier - - -parameter_mode_modifier + + +a - - -; + + +dynamic - - -} + + +yield - - -primary_expression + + +2 - - -< + + +explicitly_typed_local_variable_declaration - - -type + + +expression_list - - -< + + +dynamic - - -method_header + + +identifier - - -i + + +non_array_type - - -array_initializer + + +expression - - -inclusive_or_expression + + +default_argument - - -parameter_array + + +method_modifier - - -method_header + + +dynamic - - -rank_specifier + + +explictly_typed_default - - -statement + + +class - - -statement + + +default_argument - - -class_declaration + + +, - - -compilation_unit - - - -method_modifiers - - - -element_access + + +identifier - - + + i - - -true + + +expression - - -Comments + + +prog - - + + ) - - -literal + + +contextual_keyword - - -Foo + + +variable_initializer - - -local_variable_initializer + + +parameter_array - - -integral_type + + +contextual_keyword - - -expression + + +identifier - - -% + + +} - - + + , - - -c - - - -yield - - - -{ - - - -explicitly_typed_local_variable_declarators - - - -fixed_parameter - - - -( - - - -{ - - - -non_array_type - - - -boolean_literal - - - -prog + + +b var - - -ref_method_modifier - - - -; - - - -method_body - - - -[ - - - -type - - - -, - - - -[ - - - -class_type - - - -statement_expression - - - -statement + + += - - -declaration_statement + + +unary_expression - - -T + + +identifier namespace_or_type_name - - -integral_type - - - -statement_expression - - - -unary_expression - - - -method_declaration - - - -base - - - -a + + +i - - -parameter_list + + +expression - - -assignment + + +identifier - - -OnError + + +primary_expression - - -parameter_mode_modifier + + +{ - - -( + + +primary_expression - - -nullable_value_type + + +int - - -) + + +dynamic - - + + non_array_type - - -identifier - - - -] - - - -statement + + +declaration_statement - - -method_modifiers + + +primary_expression - - -method_body + + +return - - -ref_method_modifier + + +argument_list - - + + identifier - - -expression - - - -base_access - - - -type - - - -contextual_keyword - - - -) - - - -{ + + +identifier - - -integral_type + + +XmlComments - - -explicitly_typed_local_variable_declaration + + +out - - -parameter_modifier + + +local_variable_initializer - - -declaration_statement + + +ref - - -expression_list + + +i - - -; + + +member_name - - -Foo + + +method_modifiers - - -fixed_parameter + + +parameter_mode_modifier - - -identifier + + +type - - -) + + +method_modifiers - - + + dynamic - - -] + + +fixed_parameter - - -} + + +Foo - - -namespace + + +identifier - - -true + + +{ - - -method_modifier + + +explicitly_typed_local_variable_declaration - - -5 + + +c - - -void + + +contextual_keyword - - -i + + +namespace_declaration - - -parameter_modifier + + +compilation_unit - - -integral_type + + +{ - - + + = - - -non_array_type + + +block - - -b + + +class_member_declaration - - -parameter_modifier + + +inclusive_or_expression - - -non_array_type + + +{ - - -identifier + + +statement - - -identifier + + +true - - -non_array_type + + +public - - -identifier + + +; local_variable_initializer - - -and_expression - - - -identifier + + +dynamic - - -method_modifier + + +[ - - -? + + +literal - - -inclusive_or_expression + + +parameter_list - - -method_body + + +integral_type - - -, + + +f - - -boolean_literal + + +additive_expression - - -int + + +namespace_member_declaration - - -type_argument_list + + +new - - -1 + + +literal - - -params + + ++ - - -variable_initializer + + +a - - -} + + +parameter_modifier - - -method_declaration + + += - - -declaration_statement + + +, - - + + identifier - - -variable_initializer - - - -XmlComments - - - -type - - - -additive_expression + + +bool - - -expression + + +statement_list - - -UndocumentedKeywords + + +{ - - -) + + +local_variable_initializer - - -( + + +parameter_modifier - - -a + + +1 - - -local_variable_initializer + + +expression - - -variable_initializer + + +rank_specifier - - -- + + +additive_expression - - -multiplicative_expression + + +. - - -and_expression + + +identifier - - -namespace_declaration + + +declaration_statement - - -out + + +int - - + + boolean_literal - - -explicitly_typed_local_variable_declarator + + +Foo + + + +{ ) - - -, + + +params - - -literal + + +statement - - -and_expression + + +partial - - -] + + +i - - -^ + + +5 - - -new + + +method_modifiers - - -dynamic + + +fixed_parameters - - -partial + + +namespace - - -dynamic + + +array_type - - -contextual_keyword + + +boolean_literal - - -i + + +explicitly_typed_local_variable_declaration - - -> + + +and_expression - - -| + + +and_expression - - -class_member_declaration + + +contextual_keyword - - -; + + +method_modifiers - - -contextual_keyword + + +statement - - -literal + + +integral_type - - -inclusive_or_expression + + +identifier - - -. + + +ref_method_modifier - - + + identifier - - -4 + + +identifier - - -public + + +method_body - - -i + + +and_expression - - -= + + +explicitly_typed_local_variable_declaration - - -f + + +local_variable_initializer - - -fixed_parameter + + +local_variable_declaration - - -explicitly_typed_local_variable_declaration + + +a - - -statement + + +explicitly_typed_local_variable_declarators - - + + +] + + + identifier - - -parameter_list + + +> + + + +int + + + +( + + + +nullable_value_type member_name - - -statement_list + + +& + + + +Comments + + + +integral_type } + + +] + + + +and_expression + + + +rank_specifier + + + +* + + + +range_expression + namespace_body - - -contextual_keyword + + +void - - + + +identifier + + + +method_header + + + +{ + + + +[ + + + type - - -variable_initializer + + +identifier - - -namespace_or_type_name + + +range_expression - - -block + + +; - - -local_variable_declaration + + +i - - + + +method_header + + + int - - -. + + +expression_statement - - -{ + + +identifier - - -* + + +ref_method_modifier - - -method_modifier + + +i - - -2 + + +statement_expression - - -identifier + + +. - - -identifier + + +method_modifier - - -= + + +base_access - - -explicitly_typed_local_variable_declaration + + +; - - -nullable_type_annotation + + +statement - - -& + + +method - - -identifier + + +element_access - - -variable_initializer + + +block - - -local_variable_declaration + + +default - - -explicitly_typed_local_variable_declarator + + +non_nullable_value_type - - -parameter_mode_modifier + + +3 - - -[ + + +a - - -primary_expression + + +, - - -return_type + + +array_creation_expression - - -member_name + + +non_array_type - - -( + + +4 - - -default_argument + + +contextual_keyword - - -rank_specifier + + +partial - - + + +explicitly_typed_local_variable_declarator + + + identifier - - -primary_expression + + +) - - -local_variable_initializer + + +method_modifiers - - -i + + +literal + + + +identifier + + + +type_argument_list - - -method_body + + +declaration_statement - - -method_declaration + + +member_name - - -( + + +literal - - -ToString + + +rank_specifier - - -, + + +i - - -additive_expression + + +non_nullable_value_type - - -5 + + +? - - -identifier + + +type - - -contextual_keyword + + +multiplicative_expression - - -explicitly_typed_local_variable_declarators + + +method_declaration - - -method_body + + +ref - - -exclusive_or_expression + + +override invocation_expression - - -invocation_expression + + +literal - - -identifier + + +} - - -identifier + + +} - - -method_modifier + + +method_declaration - - -return + + +parameter_modifier - - -, + + +> - - -, + + +[ - - -explicitly_typed_local_variable_declarator + + +} - - -method_header + + +method_declaration - - -explicitly_typed_local_variable_declarator + + +[ - - -parameter_modifier + + += - - -) + + +type - - -int + + +c - - -int + + +; - - -identifier + + +| - - -= + + +contextual_keyword - - -statement_list + + +exclusive_or_expression - - -ToString + + +fixed_parameters - - -return_type + + +variable_initializer - - -default_argument + + +local_variable_declaration - - -statement + + +int - - -type + + +% - - + + identifier - - -namespace_member_declaration + + +) + + + +2 + + + +parameter_mode_modifier + + + +[ + + + +] ( - - + + +false + + + identifier - - -equality_expression + + +return_statement - - -partial + + +invocation_expression + + + +class_body + + + +nullable_type_annotation - - -block + + +public - - -; + + +method_body - - + + f - - -} - contextual_keyword - - -method_modifiers - - - -string + + +block - - -local_variable_declaration + + +method_body - - -^ + + +assignment - - -return_type + + +simple_type - - -c + + +statement_expression - - -member_name + + +non_array_type - - -literal + + +void - - -explicitly_typed_local_variable_declarators + + +type - - -integral_type + + +& - - -assignment_operator + + +ref_method_modifier - - -dynamic + + +identifier - - + + identifier - - -and_expression + + +T - - -equality_expression + + +parameter_mode_modifier - - -c + + +( - - -{ + + +; - - -class_member_declaration + + +namespace_or_type_name - - -type + + +method_modifier - - -public + + +fixed_parameter - - -nullable_type_annotation + + +void - - -array_type + + +and_expression - - -= + + +Params - - -literal + + +non_array_type - - -identifier + + +local_variable_declaration - - -] + + +method_header - - + + +out + + + +} + + + +explicitly_typed_local_variable_declarators + + + +i + + + identifier - - -multiplicative_expression + + +block - - -array_type + + +/ - - -boolean_literal + + +Params - - -2 + + +identifier - - -primary_expression + + +class_member_declaration - - + + += + + + i - - -false + + +( - - -{ + + +) - - -class_member_declaration + + +statement_list + + + +statement + + + +ToString - - -return_type + + +qualified_identifier - - -/ + + +explicitly_typed_local_variable_declarator - - -identifier + + +additive_expression - - -explicitly_typed_local_variable_declaration + + +local_variable_declaration - - -rank_specifier + + +parameter_array - - -and_expression + + +method_body - - -ref + + +identifier - - -method_modifiers + + +exclusive_or_expression - - -object_creation_expression + + +rank_specifier - - -fixed_parameters + + +statement - - -} + + +variable_initializer_list - - -non_nullable_value_type + + +. - - -literal + + +local_variable_initializer - - -method_header + + +< - - -> + + +parameter_mode_modifier - - -member_name + + +) - - -class_member_declaration + + +nullable_type_annotation - - + + ; - - -simple_type + + +return_type - - -default + + +i - - -] + + +multiplicative_expression - - -type_argument_list + + +identifier expression_statement - - -[ + + +identifier - - -argument_list + + +method_declaration - - -explicitly_typed_local_variable_declarator + + +variable_initializer - - -method + + +variable_initializer - - -multiplicative_expression + + +, - - -statement + + +void - - -? + + +identifier - - -block + + +type - - -declaration_statement + + +range_expression - - -additive_expression + + +array_type - - -identifier + + +literal - - -identifier + + +class_member_declaration - - -identifier + + +statement - - -explicitly_typed_local_variable_declarators + + +boolean_literal - - -void + + +return_type - - -type + + +return_type - - -i + + +; + + + +method_declaration + + + +explicitly_typed_local_variable_declarator ( - - -a + + +] + + + +member_name + + + +variable_initializer - - -i + + +explicitly_typed_local_variable_declarator - - -declaration_statement + + +| - - -literal + + +member_access - - -variable_initializer_list + + +explicitly_typed_local_variable_declarators - - -expression + + +identifier - - -local_variable_declaration + + +nullable_value_type - - -contextual_keyword + + +equality_expression - - -= + + +fixed_parameter - - + + +string + + + type - - -i + + +explicitly_typed_local_variable_declarators - - -. + + +^ - - -b + + +identifier - - -multiplicative_expression + + +class_declaration - - -parameter_array + + += - - -unary_expression + + +, - - -method_modifiers + + +dynamic - - -method_declaration + + +OnError - - -identifier + + +integral_type - - -identifier + + +inclusive_or_expression - - -} + + +( - - -) + + +and_expression - - -multiplicative_expression + + +false - - + + +exclusive_or_expression + + + identifier - - -method_declaration + + +rank_specifier - - -bool + + +explicitly_typed_local_variable_declaration - - -& + + +assignment_operator - - -[ + + +exclusive_or_expression - - -identifier + + +; - - -, + + +contextual_keyword - - -a + + +array_type - - -class_member_declaration + + +) - - -class_body + + +contextual_keyword - - -fixed_parameter + + +5 - - -identifier + + +equality_expression - - -method_header + + +ToString - - -| + + +return_type - - -and_expression + + +) - - -inclusive_or_expression + + +method_header - - -type_argument + + +c - - + + [ - - -type_argument - - - -void + + +explicitly_typed_local_variable_declarators - - -explictly_typed_default + + +public - - -block + + +ref_method_modifier - - + + identifier - - -public - - - -return_type + + +class_member_declaration - - -i + + +, - - -= + + +declaration_statement - - -( + + +method_modifier - - -exclusive_or_expression + + +local_variable_declaration - - + + type - - -parameter_mode_modifier - - - -local_variable_initializer + + +} - - -ref_method_modifier + + +inclusive_or_expression - - -array_type + + +literal - - -; + + +base - - -class + + +i - - -return_statement + + +params - - + + . - - -dynamic + + +[ - - -= + + +, ] - - -contextual_keyword - - - -int - - - -dynamic + + += - - -{ + + +primary_expression - - -[ + + +^ - - -+ + + +member_name - - -array_creation_expression + + +< - - -contextual_keyword + + +explicitly_typed_local_variable_declarator - - + + identifier - - -unary_expression - - - -ref - - - -params - - - -explicitly_typed_local_variable_declaration - - - -new + + +fixed_parameter - - -false + + +method_header - - -; + + +declaration_statement - - + + i - - -( + + +- - - -fixed_parameters + + +return_type - - -qualified_identifier + + +? - - -dynamic + + +object_creation_expression - - -) + + +] - - -rank_specifier + + +type_argument_list - - -Params + + +multiplicative_expression - - -non_nullable_value_type + + +boolean_literal - - -ref_method_modifier + + +( - - -void + + +true + + + +identifier \ No newline at end of file diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.gruntree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.gruntree.red.txt index 759035fb6..e86bc5836 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.gruntree.red.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.gruntree.red.txt @@ -116,7 +116,7 @@ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ * ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ -⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 3 @@ -136,7 +136,7 @@ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ * ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ -⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 4 @@ -320,7 +320,7 @@ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ % ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ -⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 2 diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.tree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.tree.red.txt index a0521fec2..26972d351 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.tree.red.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.tree.red.txt @@ -1 +1 @@ -(prog (compilation_unit (namespace_declaration namespace (qualified_identifier (identifier Comments) . (identifier XmlComments) . (identifier UndocumentedKeywords)) (namespace_body { (namespace_member_declaration (class_declaration class (identifier CSharp6Features) (class_body { (class_member_declaration (method_declaration (method_modifiers (method_modifier async)) (return_type void) (method_header (member_name (identifier Test)) ( )) (method_body (block { (statement_list (statement (expression_statement (statement_expression (invocation_expression (primary_expression (identifier WriteLine)) ( (argument_list (invocation_expression (primary_expression (identifier Sqrt)) ( (argument_list (additive_expression (additive_expression (multiplicative_expression (multiplicative_expression (literal 3)) * (unary_expression (literal 3)))) + (multiplicative_expression (multiplicative_expression (literal 4)) * (unary_expression (literal 4))))) ))) ))) ;)) (statement (expression_statement (statement_expression (invocation_expression (primary_expression (identifier WriteLine)) ( (argument_list (additive_expression (additive_expression (identifier Friday)) - (multiplicative_expression (identifier Monday)))) ))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier range) = (expression (invocation_expression (primary_expression (identifier Range)) ( (argument_list (argument (literal 5)) , (argument (literal 17))) )))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier even) = (expression (invocation_expression (primary_expression (member_access (primary_expression (identifier range)) . (identifier Where))) ( (argument_list (lambda_expression (anonymous_function_signature (identifier i)) => (anonymous_function_body (equality_expression (equality_expression (multiplicative_expression (multiplicative_expression (identifier i)) % (unary_expression (literal 2)))) == (relational_expression (literal 0)))))) )))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier length) = (local_variable_initializer (null_conditional_member_access (primary_expression (identifier customers)) ? . (identifier Length))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (identifier Customer)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier first) = (local_variable_initializer (null_conditional_element_access (primary_expression (identifier customers)) ? [ (argument_list (literal 0)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier length) = (local_variable_initializer (null_coalescing_expression (conditional_or_expression (null_conditional_member_access (primary_expression (identifier customers)) ? . (identifier Length))) ?? (null_coalescing_expression (literal 0)))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier first) = (local_variable_initializer (null_conditional_member_access (primary_expression (null_conditional_member_access (primary_expression (null_conditional_element_access (primary_expression (identifier customers)) ? [ (argument_list (literal 0)) ])) ? . (identifier Orders))) ? . (identifier Count) (dependent_access ( )))))))) ;)) (statement (expression_statement (statement_expression (null_conditional_invocation_expression (null_conditional_member_access (primary_expression (identifier PropertyChanged)) ? . (identifier Invoke)) ( (argument_list (argument (this_access this)) , (argument (identifier args))) ))) ;))) })))) }))) })))) +(prog (compilation_unit (namespace_declaration namespace (qualified_identifier (identifier Comments) . (identifier XmlComments) . (identifier UndocumentedKeywords)) (namespace_body { (namespace_member_declaration (class_declaration class (identifier CSharp6Features) (class_body { (class_member_declaration (method_declaration (method_modifiers (method_modifier async)) (return_type void) (method_header (member_name (identifier Test)) ( )) (method_body (block { (statement_list (statement (expression_statement (statement_expression (invocation_expression (primary_expression (identifier WriteLine)) ( (argument_list (invocation_expression (primary_expression (identifier Sqrt)) ( (argument_list (additive_expression (additive_expression (multiplicative_expression (multiplicative_expression (literal 3)) * (range_expression (literal 3)))) + (multiplicative_expression (multiplicative_expression (literal 4)) * (range_expression (literal 4))))) ))) ))) ;)) (statement (expression_statement (statement_expression (invocation_expression (primary_expression (identifier WriteLine)) ( (argument_list (additive_expression (additive_expression (identifier Friday)) - (multiplicative_expression (identifier Monday)))) ))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier range) = (expression (invocation_expression (primary_expression (identifier Range)) ( (argument_list (argument (literal 5)) , (argument (literal 17))) )))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier even) = (expression (invocation_expression (primary_expression (member_access (primary_expression (identifier range)) . (identifier Where))) ( (argument_list (lambda_expression (anonymous_function_signature (identifier i)) => (anonymous_function_body (equality_expression (equality_expression (multiplicative_expression (multiplicative_expression (identifier i)) % (range_expression (literal 2)))) == (relational_expression (literal 0)))))) )))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier length) = (local_variable_initializer (null_conditional_member_access (primary_expression (identifier customers)) ? . (identifier Length))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (identifier Customer)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier first) = (local_variable_initializer (null_conditional_element_access (primary_expression (identifier customers)) ? [ (argument_list (literal 0)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier length) = (local_variable_initializer (null_coalescing_expression (conditional_or_expression (null_conditional_member_access (primary_expression (identifier customers)) ? . (identifier Length))) ?? (null_coalescing_expression (literal 0)))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier first) = (local_variable_initializer (null_conditional_member_access (primary_expression (null_conditional_member_access (primary_expression (null_conditional_element_access (primary_expression (identifier customers)) ? [ (argument_list (literal 0)) ])) ? . (identifier Orders))) ? . (identifier Count) (dependent_access ( )))))))) ;)) (statement (expression_statement (statement_expression (null_conditional_invocation_expression (null_conditional_member_access (primary_expression (identifier PropertyChanged)) ? . (identifier Invoke)) ( (argument_list (argument (this_access this)) , (argument (identifier args))) ))) ;))) })))) }))) })))) diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.tree.svg b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.tree.svg index 8937fa3ad..5a1cdd607 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.tree.svg +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-R/Reference/sample.tree.svg @@ -307,1244 +307,1244 @@ - - + + +return_type + + + +primary_expression + + + identifier - - -nullable_type_annotation + + +) - - + + +customers + + + = - - + + +qualified_identifier + + + +expression_statement + + + +literal + + + +0 + + + +; + + + identifier - - -3 + + +Test - - + + primary_expression - - -range + + +identifier - - -4 + + +local_variable_declaration + + + +null_conditional_member_access + + + +statement_list + + + +explicitly_typed_local_variable_declarators literal - - -primary_expression - - - -] - - - -i + + +- - - -identifier + + +statement - - -argument_list + + +Invoke additive_expression - - -null_conditional_member_access - - - -type - - - -. - - - -) + + +identifier - - -statement + + +identifier argument_list - - -identifier + + +literal - - -explicitly_typed_local_variable_declarator + + +i - - -expression_statement + + +primary_expression - - + + identifier - - -multiplicative_expression + + += - - -) + + +Orders implicitly_typed_local_variable_declaration - - -primary_expression + + +; - - -type + + +null_conditional_invocation_expression - - -method_body + + +. - - -int + + +nullable_type_annotation - - + + +var + + + +) + + + +; + + + identifier - - -Friday + + +integral_type - - -? + + +identifier - - -= + + +non_nullable_value_type + + + +local_variable_declaration + + + +identifier first - - -argument - - - -statement_list + + +argument_list - - -; + + +local_variable_initializer - - -customers + + +method_header - - -primary_expression - - - -primary_expression - - - -namespace_declaration - - - -literal - - - -non_nullable_value_type - - - -null_conditional_member_access - - - -primary_expression - - - -declaration_statement + + +statement - - -block + + +explicitly_typed_local_variable_declarator - - -5 + + +; - - -null_conditional_invocation_expression + + +explicitly_typed_local_variable_declarators - - -? + + +) statement_expression - - -Length + + +int - - -implicitly_typed_local_variable_declarator + + +null_coalescing_expression - - -?? + + +statement - - -identifier + + +namespace_body - - -. + + +identifier - - -literal + + +additive_expression - - -explicitly_typed_local_variable_declaration + + +invocation_expression - - -literal + + +? - - -explicitly_typed_local_variable_declarators + + +statement - - -( + + +% - - -invocation_expression + + +explicitly_typed_local_variable_declarator - - -( + + +type - - -identifier + + +i - - -identifier + + +. - - -WriteLine + + +implicitly_typed_local_variable_declarator - - -equality_expression + + +primary_expression - - -argument + + +null_conditional_member_access - - -nullable_value_type + + +type - - -identifier + + +this - - -multiplicative_expression + + +WriteLine - - -literal + + +declaration_statement ( - - -argument_list - - - -compilation_unit - - - -identifier - identifier - - -Range - - - -. - - - -identifier - - - -declaration_statement + + +conditional_or_expression - - -=> + + +args - - -primary_expression + + +expression - - -explicitly_typed_local_variable_declarators + + +} - - -. + + +( - - + + local_variable_initializer - - -statement_expression + + +type - - + + +? + + + ( - - -statement + + +?? - - -prog + + +identifier - - + + +range_expression + + + ; - - + + argument + + +invocation_expression + + + +? + + + +; + + + +PropertyChanged + + + +local_variable_initializer + + + +primary_expression + + + +( + + + +explicitly_typed_local_variable_declarators + + + +class_member_declaration + + + +length + identifier - - -explicitly_typed_local_variable_declaration - - - -namespace_member_declaration + + +2 - - -== + + +primary_expression - - -( + + +implicitly_typed_local_variable_declarator statement - - -Where - - - -invocation_expression + + +explicitly_typed_local_variable_declarator - - -argument_list + + +statement - - -argument_list + + +namespace - - -explicitly_typed_local_variable_declaration + + +CSharp6Features - - -; + + +5 - - -) + + +. = - - -) - - - -] - - - + + int - - -. - - - -this_access - - - -local_variable_initializer - - - + + [ - - -argument + + +( - - + + identifier - - -implicitly_typed_local_variable_declaration - - - -local_variable_initializer - - - -CSharp6Features - - - -argument_list + + +multiplicative_expression - - -; + + +WriteLine - - -= + + +nullable_value_type - - -literal + + +identifier - - -{ + + +statement_expression - - + + literal - - -Sqrt - - - -% + + +* - - -{ + + +invocation_expression - - -identifier + + +expression - - -literal + + +local_variable_declaration - - -nullable_type_annotation + + +argument_list - - -identifier + + +nullable_value_type - - -* + + +this_access statement - - -expression_statement - - - -Comments - - - -primary_expression - - - -range - - - -this - - - -multiplicative_expression + + +Monday - - + + argument_list - - -null_coalescing_expression + + +identifier - - -} + + +( - - -conditional_or_expression + + +multiplicative_expression - - + + identifier - - -class_declaration + + +null_conditional_element_access - - -statement + + +4 - - + + local_variable_declaration - - + + identifier - - -statement - - - -method_modifier - - - -length - - - -argument_list - - - -multiplicative_expression + + +primary_expression - - -+ + + +argument - - + + identifier - - -local_variable_declaration - - - -( - - - -explicitly_typed_local_variable_declarators - - - -, - - - -nullable_value_type + + +0 - - -expression_statement + + +] - - + + ? - - -identifier - - - -identifier - - - -identifier + + +3 - - -identifier + + +Length - - -Invoke + + +length - - -. + + +{ - - -* + + +literal - - -integral_type + + +customers - - -null_conditional_member_access + + +multiplicative_expression - - -lambda_expression + + +argument 17 - - -2 - - - -3 + + +identifier UndocumentedKeywords - - -multiplicative_expression - - - -declaration_statement - - - -dependent_access + + +explicitly_typed_local_variable_declaration - - + + primary_expression - - -var + + +identifier - - -multiplicative_expression + + +int - - -statement + + +4 - - -explicitly_typed_local_variable_declarators + + +3 - - -statement + + +equality_expression - - -) + + +Comments - - -identifier + + +statement_expression - - -unary_expression + + +method_modifier - - -identifier + + +block - - -equality_expression + + +Friday + + + +void + + + +primary_expression + + + +member_name + + + +=> + + + +literal + + + +additive_expression identifier - - -args - - - -null_conditional_member_access + + +multiplicative_expression - - -literal + + +) - - -( + + +primary_expression - - -integral_type + + +null_conditional_member_access ? - - -Customer + + +. - - -Monday + + +. - - -declaration_statement + + +} - - -explicitly_typed_local_variable_declarator + + +. - - -[ + + +async - - -multiplicative_expression + + +method_body - - -0 + + +primary_expression - - -{ + + +Where - - -identifier + + +member_access + + + +] XmlComments - - -explicitly_typed_local_variable_declarator + + +multiplicative_expression - - + + identifier + + +( + + + +) + identifier - - -statement + + +local_variable_declaration - - -0 + + +( - - -? + + +class - - -Test + + +; - - -0 + + +customers - - -null_conditional_member_access + + +expression_statement - - -i + + +anonymous_function_body - - -type + + +* - - -Orders + + +range - - -qualified_identifier + + +explicitly_typed_local_variable_declarator - - -0 + + +, - - -customers + + +0 - - -null_conditional_element_access + + +null_conditional_member_access - - -invocation_expression + + +nullable_type_annotation - - + + additive_expression - - -member_name + + +multiplicative_expression - - -expression + + +argument_list - - -method_declaration + + +Range - - -. + + +local_variable_initializer - - -class + + +compilation_unit - - -- + + +invocation_expression - - -= + + +argument - - -namespace + + +null_conditional_element_access - - -anonymous_function_signature + + +dependent_access - - -non_nullable_value_type + + +local_variable_declaration - - -type + + +identifier + + + +declaration_statement + + + +declaration_statement declaration_statement - - -WriteLine + + +identifier - - -? + + +namespace_member_declaration - - -additive_expression + + +. - - -invocation_expression + + +primary_expression + + + +integral_type + + + +, + + + +lambda_expression + + + +literal + + + +) + + + +Count primary_expression - - -null_conditional_element_access + + +0 - - -local_variable_declaration + + +anonymous_function_signature - - -} + + +Length - - -class_body + + +even - - -local_variable_declaration + + +null_coalescing_expression - - -implicitly_typed_local_variable_declarator + + +range_expression - - -; + + +relational_expression - - -async + + +literal - - -method_modifiers + + +implicitly_typed_local_variable_declaration - - -) + + +expression_statement + + + +explicitly_typed_local_variable_declaration var - - -? - - - -= + + +multiplicative_expression - - -primary_expression + + +namespace_declaration - - -local_variable_declaration + + +argument_list - - -; + + +[ - - + + identifier - - -method_header + + +== - - -statement_expression + + +method_modifiers - - -. + + +Customer - - -namespace_body + + += - - -expression + + +identifier - - -even + + +? - - + + +range_expression + + + +prog + + + ; - - -Length + + +declaration_statement - - -unary_expression + + +class_body - - -literal + + +} - - -primary_expression + + +method_declaration - - -int + + += - - -additive_expression + + +{ - - -invocation_expression + + +identifier - - -customers + + +equality_expression - - -return_type + + +? - - -anonymous_function_body + + +argument_list - - -customers + + +{ - - -integral_type + + +declaration_statement - - -local_variable_declaration + + +? - - -local_variable_initializer + + +first - - -length + + +. - - -primary_expression + + +null_conditional_member_access - - -member_access + + +identifier - - -null_coalescing_expression + + +class_declaration - - -; + + +type - - -identifier + + +explicitly_typed_local_variable_declaration - - + + identifier - - -) + + +Sqrt - - -) + + +invocation_expression - - -PropertyChanged + + +range - - -first + + +statement - - -, + + +literal - - -explicitly_typed_local_variable_declaration + + +) - - -void + + +; - - -unary_expression + + += - - -class_member_declaration + + +identifier - - -( + + +non_nullable_value_type - - -relational_expression + + +integral_type - - -; + + ++ - - -? + + +explicitly_typed_local_variable_declaration - - -explicitly_typed_local_variable_declarator + + +literal - - -4 + + +identifier - - -literal + + +? - - -} + + +) - - -declaration_statement + + +argument_list - - -Count + + +customers - - -? + + +literal + + + +explicitly_typed_local_variable_declarators + + + +statement \ No newline at end of file diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.gruntree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.gruntree.red.txt index d915780a3..c93e194b1 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.gruntree.red.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.gruntree.red.txt @@ -158,10 +158,10 @@ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ shift_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ -⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ > ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ -⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ primary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ c diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.stderr.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.stderr.txt index 19ef2924c..6cbf4b5e8 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.stderr.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.stderr.txt @@ -1,3 +1,3 @@ line 10:12 no viable alternative at input '>' -line 10:14 extraneous input '>' expecting {'-', '--', '!', '(', '&', '+', '++', '~', 'add', 'alias', 'ascending', 'async', 'await', 'base', 'bool', 'by', 'byte', 'char', 'checked', 'decimal', 'delegate', 'descending', 'double', 'dynamic', 'equals', 'float', 'from', 'get', 'global', 'group', 'int', 'into', 'join', 'let', 'long', 'nameof', 'new', 'notnull', 'object', 'on', 'orderby', 'partial', 'remove', 'sbyte', 'select', 'set', 'short', 'sizeof', 'stackalloc', 'string', 'this', 'typeof', 'uint', 'ulong', 'unchecked', 'unmanaged', 'ushort', 'value', 'var', 'when', 'where', 'yield', 'default', 'null', 'true', 'false', '*', Simple_Identifier, Integer_Literal, Real_Literal, Character_Literal, String_Literal, Interpolated_Regular_String_Start, Interpolated_Verbatim_String_Start} +line 10:14 extraneous input '>' expecting {'-', '--', '!', '..', '(', '&', '^', '+', '++', '~', 'add', 'alias', 'ascending', 'async', 'await', 'base', 'bool', 'by', 'byte', 'char', 'checked', 'decimal', 'delegate', 'descending', 'double', 'dynamic', 'equals', 'float', 'from', 'get', 'global', 'group', 'int', 'into', 'join', 'let', 'long', 'nameof', 'new', 'notnull', 'object', 'on', 'orderby', 'partial', 'remove', 'sbyte', 'select', 'set', 'short', 'sizeof', 'stackalloc', 'string', 'this', 'typeof', 'uint', 'ulong', 'unchecked', 'unmanaged', 'ushort', 'value', 'var', 'when', 'where', 'yield', 'default', 'null', 'true', 'false', '*', Simple_Identifier, Integer_Literal, Real_Literal, Character_Literal, String_Literal, Interpolated_Regular_String_Start, Interpolated_Verbatim_String_Start} line 11:8 no viable alternative at input '>' diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.tree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.tree.red.txt index bc5a48544..9319e7c52 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.tree.red.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.tree.red.txt @@ -1 +1 @@ -(prog (compilation_unit (class_declaration class (identifier RightShift) (class_body { (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier RightShift)) ( )) (method_body (block { (statement_list (statement (expression_statement (statement_expression (assignment (unary_expression (identifier a)) (assignment_operator =) (expression (shift_expression (shift_expression (identifier b)) (right_shift > >) (additive_expression (identifier c)))))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier d)) (assignment_operator (right_shift_assignment > >=)) (expression (identifier e)))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier a)) (assignment_operator =) (expression (relational_expression (relational_expression (identifier b)) > (shift_expression (unary_expression > (primary_expression (identifier c)))))))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier d)) (assignment_operator > >=) (expression (identifier e)))) ;))) })))) })))) +(prog (compilation_unit (class_declaration class (identifier RightShift) (class_body { (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier RightShift)) ( )) (method_body (block { (statement_list (statement (expression_statement (statement_expression (assignment (unary_expression (identifier a)) (assignment_operator =) (expression (shift_expression (shift_expression (identifier b)) (right_shift > >) (additive_expression (identifier c)))))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier d)) (assignment_operator (right_shift_assignment > >=)) (expression (identifier e)))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier a)) (assignment_operator =) (expression (relational_expression (relational_expression (identifier b)) > (shift_expression (range_expression > (unary_expression (identifier c)))))))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier d)) (assignment_operator > >=) (expression (identifier e)))) ;))) })))) })))) diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.tree.svg b/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.tree.svg index a2f9245dc..721877c1e 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.tree.svg +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/RightShift/Reference/sample.tree.svg @@ -73,10 +73,10 @@ - - - - + + + + @@ -94,392 +94,392 @@ - - -; - - - -right_shift_assignment + + +relational_expression - - -class_member_declaration + + +prog - - -block + + +> - - + + identifier - - -e - - - -unary_expression - - - -statement - - - -unary_expression - - - -class_declaration - - - -class - - - -statement_expression - - - + + expression_statement - - -> - assignment - - -method_body - - - -statement + + +right_shift_assignment - - + + identifier - - -d + + +expression - - -identifier + + +expression_statement - - -assignment + + +unary_expression + + + +identifier expression - - -relational_expression - identifier - - -RightShift - - - -RightShift + + +unary_expression - - -} + + +; - - -statement_list + + +shift_expression - - -primary_expression + + +void - - + + } - - -c + + +e - - -return_type + + +assignment_operator - - -identifier + + +; - - + + identifier - - -{ + + +( - - -= + + +block - - -identifier + + +assignment_operator - - -unary_expression + + +statement_list - - -assignment_operator + + +expression - - -> + + +statement_expression - - -> + + +method_declaration - - -; + + +identifier - - -b + + +shift_expression - - -; + + +{ - - -assignment + + +method_modifiers - - -c + + +unary_expression - - -relational_expression + + +statement - - -> + + +expression_statement - - + + identifier - - -statement_expression + + +range_expression - - ->= + + +additive_expression - - -prog + + +shift_expression - - -b + + +identifier - - -statement + + += - - -void + + +c - - -method_modifiers + + +assignment - - -) + + +expression - - -= + + +method_header - - -shift_expression + + +statement - - -member_name + + +c - - + + { - - -expression_statement + + +> - - + + identifier - - -right_shift - - - + + identifier - - -expression - - - -assignment_operator + + +class_member_declaration - - -d + + +assignment expression_statement - - -statement_expression + + +>= assignment_operator + + +; + + + +> + >= - - -; + + +class_declaration - - -( + + +identifier - - -shift_expression + + +statement a - - -class_body + + +; + + + +> + + + +unary_expression + + + +> + + + +) + + + +method_body + + + +d + + + +e a - - -expression + + +statement_expression - - -method_declaration + + +RightShift - - -expression + + +relational_expression - - -unary_expression + + +d compilation_unit - - -statement + + +> - - -e + + +statement_expression - - + + +RightShift + + + +member_name + + + unary_expression - - -method_header + + +statement - - + + +identifier + + + +return_type + + + assignment_operator - - -expression_statement + + +b - - -identifier + + +assignment + + + +b statement_expression - - -> - - - -> + + += - - -additive_expression + + +right_shift - - -identifier + + +} - - -assignment + + +class - - -shift_expression + + +class_body \ No newline at end of file diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Element Access/ReadMe.md b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Element Access/ReadMe.md index 348083c6e..60ff2220b 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Element Access/ReadMe.md +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Element Access/ReadMe.md @@ -9,4 +9,4 @@ The sample contains both valid and invalid samples, the semantic errors the latt produce are checked – the reference errors are in `Reference/sample.stderr.txt` The check is a semantic one only, the code still parses successfully and the parse tree -is checked for correctness as with other samples. \ No newline at end of file +is checked for correctness as with other samples. diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/ReadMe.md b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/ReadMe.md new file mode 100644 index 000000000..db692992f --- /dev/null +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/ReadMe.md @@ -0,0 +1 @@ +# Sample: Index & Range expressions diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.gruntree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.gruntree.red.txt new file mode 100644 index 000000000..babc97bfa --- /dev/null +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.gruntree.red.txt @@ -0,0 +1,1017 @@ +⎛ +⎜ prog +⎜ ⎛ +⎜ ⎜ compilation_unit +⎜ ⎜ ⎛ +⎜ ⎜ ⎜ class_declaration +⎜ ⎜ ⎜ class +⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ IndexAndRangeExpressions +⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ class_body +⎜ ⎜ ⎜ ⎜ { +⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ class_member_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ method_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ method_modifiers +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ return_type +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ void +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ method_header +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ member_name +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ IndexAndRangeExpressions_1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ( +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ) +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ method_body +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ block +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ { +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement_list +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ a +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ^ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ b +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ^ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ c +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 0 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ d +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ e +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ object_creation_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ new +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ type +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ Struct +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ( +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ) +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ f +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ e +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ * +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 2 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ g +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ e +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ * +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ h +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ e +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ * +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ i +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ e +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ * +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 2 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ j +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ / +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ e +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ k +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ^ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 2 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ / +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ e +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ l +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ^ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ / +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ e +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ m +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ multiplicative_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ^ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 2 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ^ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ / +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ e +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ n +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ member_access +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ primary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ parenthesized_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ( +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 6 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ) +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ . +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ End +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ o +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ member_access +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ primary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ b +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ . +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ Start +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 5 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ p +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ member_access +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ primary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ parenthesized_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ( +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 3 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ) +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ . +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ Start +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 5 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ oops +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ parenthesized_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ( +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 3 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ) +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 5 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ oops +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ parenthesized_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ( +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 3 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 5 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ) +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ declaration_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declaration +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ var +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ implicitly_typed_local_variable_declarator +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ identifier +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ oops +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ = +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ range_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 1 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ unary_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ literal +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 3 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ .. +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎛ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ expression_statement +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ statement_expression +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ 5 +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ; +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ } +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎜ ⎜ } +⎜ ⎜ ⎜ ⎝ +⎜ ⎜ ⎝ +⎜ ⎝ +⎝ diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.stderr.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.stderr.txt new file mode 100644 index 000000000..8761e9bbd --- /dev/null +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.stderr.txt @@ -0,0 +1 @@ +line 24:21 mismatched input '..' expecting {'-', '--', '->', ';', '!', '!=', '?', '.', '(', '[', '&', '&&', '%', '^', '+', '++', '<', '<<', '<=', '==', '>', '>=', '|', '||', 'as', 'is', '*', '/'} diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tokens.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tokens.txt new file mode 100644 index 000000000..53045c1f6 --- /dev/null +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tokens.txt @@ -0,0 +1,176 @@ +[@0,0:4='class',<'class'>,1:0] +[@1,6:29='IndexAndRangeExpressions',,1:6] +[@2,31:31='{',<'{'>,2:0] +[@3,36:39='void',<'void'>,3:3] +[@4,41:66='IndexAndRangeExpressions_1',,3:8] +[@5,67:67='(',<'('>,3:34] +[@6,68:68=')',<')'>,3:35] +[@7,73:73='{',<'{'>,4:3] +[@8,81:83='var',<'var'>,5:6] +[@9,85:85='a',,5:10] +[@10,87:87='=',<'='>,5:12] +[@11,89:89='^',<'^'>,5:14] +[@12,90:90='1',,5:15] +[@13,91:91=';',<';'>,5:16] +[@14,99:101='var',<'var'>,6:6] +[@15,103:103='b',,6:10] +[@16,105:105='=',<'='>,6:12] +[@17,107:108='..',<'..'>,6:14] +[@18,109:109='^',<'^'>,6:16] +[@19,110:110='1',,6:17] +[@20,111:111=';',<';'>,6:18] +[@21,119:121='var',<'var'>,7:6] +[@22,123:123='c',,7:10] +[@23,125:125='=',<'='>,7:12] +[@24,127:127='0',,7:14] +[@25,128:129='..',<'..'>,7:15] +[@26,130:130=';',<';'>,7:17] +[@27,138:140='var',<'var'>,8:6] +[@28,142:142='d',,8:10] +[@29,144:144='=',<'='>,8:12] +[@30,146:147='..',<'..'>,8:14] +[@31,148:148=';',<';'>,8:16] +[@32,156:158='var',<'var'>,9:6] +[@33,160:160='e',,9:10] +[@34,162:162='=',<'='>,9:12] +[@35,164:166='new',<'new'>,9:14] +[@36,168:173='Struct',,9:18] +[@37,174:174='(',<'('>,9:24] +[@38,175:175=')',<')'>,9:25] +[@39,176:176=';',<';'>,9:26] +[@40,218:220='var',<'var'>,10:6] +[@41,222:222='f',,10:10] +[@42,224:224='=',<'='>,10:12] +[@43,226:226='e',,10:14] +[@44,228:228='*',<'*'>,10:16] +[@45,230:230='1',,10:18] +[@46,232:233='..',<'..'>,10:20] +[@47,235:235='2',,10:23] +[@48,236:236=';',<';'>,10:24] +[@49,244:246='var',<'var'>,11:6] +[@50,248:248='g',,11:10] +[@51,250:250='=',<'='>,11:12] +[@52,252:252='e',,11:14] +[@53,254:254='*',<'*'>,11:16] +[@54,256:257='..',<'..'>,11:18] +[@55,258:258=';',<';'>,11:20] +[@56,266:268='var',<'var'>,12:6] +[@57,270:270='h',,12:10] +[@58,272:272='=',<'='>,12:12] +[@59,274:274='e',,12:14] +[@60,276:276='*',<'*'>,12:16] +[@61,278:278='1',,12:18] +[@62,279:280='..',<'..'>,12:19] +[@63,281:281=';',<';'>,12:21] +[@64,289:291='var',<'var'>,13:6] +[@65,293:293='i',,13:10] +[@66,295:295='=',<'='>,13:12] +[@67,297:297='e',,13:14] +[@68,299:299='*',<'*'>,13:16] +[@69,301:302='..',<'..'>,13:18] +[@70,303:303='2',,13:20] +[@71,304:304=';',<';'>,13:21] +[@72,312:314='var',<'var'>,14:6] +[@73,316:316='j',,14:10] +[@74,318:318='=',<'='>,14:12] +[@75,320:321='..',<'..'>,14:14] +[@76,323:323='/',<'/'>,14:17] +[@77,325:325='e',,14:19] +[@78,326:326=';',<';'>,14:20] +[@79,334:336='var',<'var'>,15:6] +[@80,338:338='k',,15:10] +[@81,340:340='=',<'='>,15:12] +[@82,342:342='^',<'^'>,15:14] +[@83,343:343='2',,15:15] +[@84,344:345='..',<'..'>,15:16] +[@85,347:347='/',<'/'>,15:19] +[@86,349:349='e',,15:21] +[@87,350:350=';',<';'>,15:22] +[@88,358:360='var',<'var'>,16:6] +[@89,362:362='l',,16:10] +[@90,364:364='=',<'='>,16:12] +[@91,366:367='..',<'..'>,16:14] +[@92,369:369='^',<'^'>,16:17] +[@93,370:370='1',,16:18] +[@94,371:371='/',<'/'>,16:19] +[@95,372:372='e',,16:20] +[@96,373:373=';',<';'>,16:21] +[@97,381:383='var',<'var'>,17:6] +[@98,385:385='m',,17:10] +[@99,387:387='=',<'='>,17:12] +[@100,389:389='^',<'^'>,17:14] +[@101,390:390='2',,17:15] +[@102,392:393='..',<'..'>,17:17] +[@103,394:394='^',<'^'>,17:19] +[@104,395:395='1',,17:20] +[@105,397:397='/',<'/'>,17:22] +[@106,399:399='e',,17:24] +[@107,400:400=';',<';'>,17:25] +[@108,408:410='var',<'var'>,18:6] +[@109,412:412='n',,18:10] +[@110,414:414='=',<'='>,18:12] +[@111,416:416='1',,18:14] +[@112,417:418='..',<'..'>,18:15] +[@113,419:419='(',<'('>,18:17] +[@114,420:421='..',<'..'>,18:18] +[@115,423:423='6',,18:21] +[@116,424:424=')',<')'>,18:22] +[@117,425:425='.',<'.'>,18:23] +[@118,426:428='End',,18:24] +[@119,429:429=';',<';'>,18:27] +[@120,437:439='var',<'var'>,19:6] +[@121,441:441='o',,19:10] +[@122,443:443='=',<'='>,19:12] +[@123,445:445='b',,19:14] +[@124,446:446='.',<'.'>,19:15] +[@125,447:451='Start',,19:16] +[@126,452:453='..',<'..'>,19:21] +[@127,454:454='5',,19:23] +[@128,455:455=';',<';'>,19:24] +[@129,463:465='var',<'var'>,20:6] +[@130,467:467='p',,20:10] +[@131,469:469='=',<'='>,20:12] +[@132,471:471='(',<'('>,20:14] +[@133,472:472='1',,20:15] +[@134,473:474='..',<'..'>,20:16] +[@135,475:475='3',,20:18] +[@136,476:476=')',<')'>,20:19] +[@137,477:477='.',<'.'>,20:20] +[@138,478:482='Start',,20:21] +[@139,483:484='..',<'..'>,20:26] +[@140,485:485='5',,20:28] +[@141,486:486=';',<';'>,20:29] +[@142,501:503='var',<'var'>,22:6] +[@143,505:508='oops',,22:10] +[@144,510:510='=',<'='>,22:15] +[@145,512:512='(',<'('>,22:17] +[@146,513:513='1',,22:18] +[@147,514:515='..',<'..'>,22:19] +[@148,516:516='3',,22:21] +[@149,517:517=')',<')'>,22:22] +[@150,518:519='..',<'..'>,22:23] +[@151,520:520='5',,22:25] +[@152,521:521=';',<';'>,22:26] +[@153,561:563='var',<'var'>,23:6] +[@154,565:568='oops',,23:10] +[@155,570:570='=',<'='>,23:15] +[@156,572:572='1',,23:17] +[@157,573:574='..',<'..'>,23:18] +[@158,575:575='(',<'('>,23:20] +[@159,576:576='3',,23:21] +[@160,577:578='..',<'..'>,23:22] +[@161,579:579='5',,23:24] +[@162,580:580=')',<')'>,23:25] +[@163,581:581=';',<';'>,23:26] +[@164,621:623='var',<'var'>,24:6] +[@165,625:628='oops',,24:10] +[@166,630:630='=',<'='>,24:15] +[@167,632:632='1',,24:17] +[@168,633:634='..',<'..'>,24:18] +[@169,635:635='3',,24:20] +[@170,636:637='..',<'..'>,24:21] +[@171,638:638='5',,24:23] +[@172,639:639=';',<';'>,24:24] +[@173,680:680='}',<'}'>,25:3] +[@174,682:682='}',<'}'>,26:0] +[@175,683:682='',,26:1] diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tree.red.txt new file mode 100644 index 000000000..2c5fdd8a8 --- /dev/null +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tree.red.txt @@ -0,0 +1 @@ +(prog (compilation_unit (class_declaration class (identifier IndexAndRangeExpressions) (class_body { (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier IndexAndRangeExpressions_1)) ( )) (method_body (block { (statement_list (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier a) = (expression (unary_expression ^ (unary_expression (literal 1))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier b) = (expression (range_expression .. (unary_expression ^ (unary_expression (literal 1)))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier c) = (expression (range_expression (unary_expression (literal 0)) ..))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier d) = (expression (range_expression ..))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier e) = (expression (object_creation_expression new (type (identifier Struct)) ( )))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier f) = (expression (multiplicative_expression (multiplicative_expression (identifier e)) * (range_expression (unary_expression (literal 1)) .. (unary_expression (literal 2)))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier g) = (expression (multiplicative_expression (multiplicative_expression (identifier e)) * (range_expression ..)))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier h) = (expression (multiplicative_expression (multiplicative_expression (identifier e)) * (range_expression (unary_expression (literal 1)) ..)))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier i) = (expression (multiplicative_expression (multiplicative_expression (identifier e)) * (range_expression .. (unary_expression (literal 2)))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier j) = (expression (multiplicative_expression (multiplicative_expression (range_expression ..)) / (range_expression (identifier e))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier k) = (expression (multiplicative_expression (multiplicative_expression (range_expression (unary_expression ^ (unary_expression (literal 2))) ..)) / (range_expression (identifier e))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier l) = (expression (multiplicative_expression (multiplicative_expression (range_expression .. (unary_expression ^ (unary_expression (literal 1))))) / (range_expression (identifier e))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier m) = (expression (multiplicative_expression (multiplicative_expression (range_expression (unary_expression ^ (unary_expression (literal 2))) .. (unary_expression ^ (unary_expression (literal 1))))) / (range_expression (identifier e))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier n) = (expression (range_expression (unary_expression (literal 1)) .. (unary_expression (member_access (primary_expression (parenthesized_expression ( (expression (range_expression .. (unary_expression (literal 6)))) ))) . (identifier End)))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier o) = (expression (range_expression (unary_expression (member_access (primary_expression (identifier b)) . (identifier Start))) .. (unary_expression (literal 5))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier p) = (expression (range_expression (unary_expression (member_access (primary_expression (parenthesized_expression ( (expression (range_expression (unary_expression (literal 1)) .. (unary_expression (literal 3)))) ))) . (identifier Start))) .. (unary_expression (literal 5))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier oops) = (expression (range_expression (unary_expression (parenthesized_expression ( (expression (range_expression (unary_expression (literal 1)) .. (unary_expression (literal 3)))) ))) .. (unary_expression (literal 5))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier oops) = (expression (range_expression (unary_expression (literal 1)) .. (unary_expression (parenthesized_expression ( (expression (range_expression (unary_expression (literal 3)) .. (unary_expression (literal 5)))) )))))))) ;)) (statement (declaration_statement (local_variable_declaration (implicitly_typed_local_variable_declaration var (implicitly_typed_local_variable_declarator (identifier oops) = (expression (range_expression (unary_expression (literal 1)) .. (unary_expression (literal 3))))))) ..)) (statement (expression_statement statement_expression 5 ;))) })))) })))) diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tree.svg b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tree.svg new file mode 100644 index 000000000..85dd1add9 --- /dev/null +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/Reference/sample.tree.svg @@ -0,0 +1,2285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +expression + + + +literal + + + +implicitly_typed_local_variable_declaration + + + +/ + + + +.. + + + +declaration_statement + + + +.. + + + += + + + +statement + + + +expression + + + +literal + + + +range_expression + + + +unary_expression + + + +.. + + + +1 + + + +; + + + +implicitly_typed_local_variable_declaration + + + +implicitly_typed_local_variable_declarator + + + +var + + + +member_access + + + +multiplicative_expression + + + += + + + +identifier + + + +multiplicative_expression + + + +1 + + + +5 + + + +; + + + +unary_expression + + + +multiplicative_expression + + + +literal + + + +implicitly_typed_local_variable_declaration + + + += + + + +) + + + +e + + + +statement_expression + + + +declaration_statement + + + +identifier + + + += + + + +declaration_statement + + + +. + + + +IndexAndRangeExpressions_1 + + + +var + + + +var + + + +} + + + +c + + + +.. + + + +; + + + +range_expression + + + +identifier + + + +multiplicative_expression + + + +return_type + + + +var + + + +multiplicative_expression + + + +declaration_statement + + + +statement + + + +parenthesized_expression + + + +unary_expression + + + +identifier + + + +* + + + +2 + + + +unary_expression + + + +statement + + + +; + + + +2 + + + +5 + + + +IndexAndRangeExpressions + + + +implicitly_typed_local_variable_declarator + + + +multiplicative_expression + + + +1 + + + +range_expression + + + +literal + + + +expression + + + +e + + + +.. + + + +identifier + + + +literal + + + +implicitly_typed_local_variable_declaration + + + +literal + + + +literal + + + +; + + + +m + + + +expression + + + +; + + + +literal + + + +identifier + + + +unary_expression + + + +l + + + +unary_expression + + + += + + + +implicitly_typed_local_variable_declarator + + + +statement + + + +{ + + + +unary_expression + + + +( + + + +5 + + + +identifier + + + +g + + + +) + + + +expression + + + +local_variable_declaration + + + +unary_expression + + + +/ + + + +implicitly_typed_local_variable_declaration + + + +implicitly_typed_local_variable_declarator + + + +implicitly_typed_local_variable_declaration + + + +implicitly_typed_local_variable_declarator + + + +primary_expression + + + +identifier + + + +unary_expression + + + +expression + + + +expression + + + +var + + + +statement + + + +literal + + + +declaration_statement + + + +identifier + + + +.. + + + +unary_expression + + + += + + + +.. + + + +expression_statement + + + +range_expression + + + += + + + += + + + +.. + + + +declaration_statement + + + += + + + +( + + + +declaration_statement + + + +1 + + + +0 + + + +literal + + + +expression + + + +oops + + + +; + + + +class_member_declaration + + + +range_expression + + + +expression + + + +implicitly_typed_local_variable_declarator + + + +.. + + + +unary_expression + + + +unary_expression + + + +unary_expression + + + +2 + + + +* + + + +implicitly_typed_local_variable_declarator + + + +; + + + +local_variable_declaration + + + +range_expression + + + +expression + + + +implicitly_typed_local_variable_declaration + + + +local_variable_declaration + + + +.. + + + +identifier + + + +range_expression + + + +multiplicative_expression + + + +1 + + + +n + + + +Start + + + +method_modifiers + + + += + + + +class_declaration + + + +identifier + + + +var + + + +unary_expression + + + +Struct + + + +unary_expression + + + +; + + + +unary_expression + + + +literal + + + +; + + + +.. + + + +identifier + + + +.. + + + +identifier + + + +expression + + + +unary_expression + + + +local_variable_declaration + + + +new + + + +implicitly_typed_local_variable_declarator + + + +unary_expression + + + +unary_expression + + + +; + + + +implicitly_typed_local_variable_declarator + + + +local_variable_declaration + + + +e + + + +range_expression + + + +local_variable_declaration + + + +expression + + + +implicitly_typed_local_variable_declarator + + + +e + + + +object_creation_expression + + + +void + + + +declaration_statement + + + +statement + + + +parenthesized_expression + + + +declaration_statement + + + +method_body + + + +a + + + +implicitly_typed_local_variable_declaration + + + +class_body + + + +statement + + + +6 + + + +statement + + + +^ + + + +p + + + +e + + + +.. + + + +expression + + + +unary_expression + + + +var + + + +; + + + +local_variable_declaration + + + +.. + + + +3 + + + +implicitly_typed_local_variable_declaration + + + +e + + + +3 + + + += + + + +implicitly_typed_local_variable_declarator + + + +k + + + +; + + + +identifier + + + +expression + + + +prog + + + +e + + + +multiplicative_expression + + + +implicitly_typed_local_variable_declaration + + + +statement + + + +statement + + + +( + + + +local_variable_declaration + + + +expression + + + +parenthesized_expression + + + +o + + + +implicitly_typed_local_variable_declarator + + + +unary_expression + + + +i + + + +implicitly_typed_local_variable_declaration + + + +) + + + +literal + + + +.. + + + +literal + + + +range_expression + + + +implicitly_typed_local_variable_declarator + + + +identifier + + + +local_variable_declaration + + + +declaration_statement + + + +^ + + + +member_name + + + +implicitly_typed_local_variable_declaration + + + +identifier + + + +.. + + + +statement + + + +declaration_statement + + + +/ + + + +implicitly_typed_local_variable_declaration + + + +range_expression + + + +3 + + + +var + + + +^ + + + +range_expression + + + +implicitly_typed_local_variable_declarator + + + +identifier + + + +identifier + + + +identifier + + + +implicitly_typed_local_variable_declarator + + + +oops + + + +multiplicative_expression + + + +multiplicative_expression + + + +( + + + +local_variable_declaration + + + +range_expression + + + +var + + + += + + + +literal + + + +multiplicative_expression + + + +identifier + + + +local_variable_declaration + + + +range_expression + + + +var + + + +; + + + +; + + + +unary_expression + + + += + + + +Start + + + +local_variable_declaration + + + +local_variable_declaration + + + +class + + + +identifier + + + +literal + + + +range_expression + + + +expression + + + +var + + + +) + + + +declaration_statement + + + +range_expression + + + +e + + + +unary_expression + + + +( + + + +5 + + + +1 + + + +implicitly_typed_local_variable_declarator + + + +local_variable_declaration + + + +f + + + +range_expression + + + +identifier + + + +oops + + + +End + + + +j + + + +unary_expression + + + +; + + + +{ + + + +parenthesized_expression + + + +* + + + +; + + + +range_expression + + + +b + + + +multiplicative_expression + + + +local_variable_declaration + + + +^ + + + +unary_expression + + + +) + + + +} + + + +statement + + + +local_variable_declaration + + + +unary_expression + + + +implicitly_typed_local_variable_declarator + + + +unary_expression + + + +3 + + + +1 + + + +var + + + +unary_expression + + + +implicitly_typed_local_variable_declaration + + + +expression + + + +expression + + + +identifier + + + += + + + +multiplicative_expression + + + +unary_expression + + + +statement + + + +expression + + + += + + + +declaration_statement + + + +implicitly_typed_local_variable_declaration + + + +literal + + + +range_expression + + + +literal + + + +; + + + +d + + + +h + + + +.. + + + +method_header + + + +range_expression + + + +declaration_statement + + + +.. + + + +2 + + + +literal + + + +unary_expression + + + +.. + + + +primary_expression + + + +unary_expression + + + +expression + + + +literal + + + +implicitly_typed_local_variable_declaration + + + +multiplicative_expression + + + +statement_list + + + +. + + + +identifier + + + +identifier + + + +.. + + + +e + + + +identifier + + + +expression + + + +literal + + + +literal + + + +method_declaration + + + +range_expression + + + +statement + + + +range_expression + + + +identifier + + + +primary_expression + + + +statement + + + +.. + + + +literal + + + +* + + + +block + + + +declaration_statement + + + +^ + + + +5 + + + +unary_expression + + + +statement + + + +var + + + += + + + +range_expression + + + +identifier + + + +var + + + +implicitly_typed_local_variable_declaration + + + +implicitly_typed_local_variable_declarator + + + +identifier + + + +statement + + + +identifier + + + += + + + +var + + + +unary_expression + + + +statement + + + +identifier + + + +local_variable_declaration + + + +unary_expression + + + +1 + + + +range_expression + + + +unary_expression + + + += + + + +expression + + + +b + + + +/ + + + +literal + + + +identifier + + + +expression + + + +1 + + + +multiplicative_expression + + + +declaration_statement + + + +identifier + + + +.. + + + +literal + + + +declaration_statement + + + +var + + + +^ + + + +identifier + + + +local_variable_declaration + + + +var + + + +var + + + +multiplicative_expression + + + +implicitly_typed_local_variable_declarator + + + +compilation_unit + + + +. + + + +range_expression + + + +local_variable_declaration + + + +type + + + +declaration_statement + + + +implicitly_typed_local_variable_declaration + + + +statement + + + +; + + + += + + + +member_access + + + +) + + + +range_expression + + + +member_access + + + +var + + + +statement + + + +1 + + + +1 + + + +literal + + + +implicitly_typed_local_variable_declaration + + + +unary_expression + + + +declaration_statement + + + +( + + \ No newline at end of file diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/_Sample_Options.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/_Sample_Options.txt new file mode 100644 index 000000000..c3810f510 --- /dev/null +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/_Sample_Options.txt @@ -0,0 +1 @@ +-ms Rules -rt \ No newline at end of file diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/sample.cs b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/sample.cs new file mode 100644 index 000000000..27fabc203 --- /dev/null +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v8/Index & Range/sample.cs @@ -0,0 +1,26 @@ +class IndexAndRangeExpressions +{ + void IndexAndRangeExpressions_1() + { + var a = ^1; + var b = ..^1; + var c = 0..; + var d = ..; + var e = new Struct(); // type with ops * and / taking Range + var f = e * 1 .. 2; + var g = e * ..; + var h = e * 1..; + var i = e * ..2; + var j = .. / e; + var k = ^2.. / e; + var l = .. ^1/e; + var m = ^2 ..^1 / e; + var n = 1..(.. 6).End; + var o = b.Start..5; + var p = (1..3).Start..5; + + var oops = (1..3)..5; // compile-time type error + var oops = 1..(3..5); // compile-time type error + var oops = 1..3..5; // compile-time syntax error + } +} \ No newline at end of file From f27b953456fcded7e21ed13dcec6ce9f59162448 Mon Sep 17 00:00:00 2001 From: Nigel-Ecma Date: Thu, 17 Jul 2025 14:49:22 +1200 Subject: [PATCH 2/8] =?UTF-8?q?=EF=B8=8FWell=20that=20was=20a=20bit=20emba?= =?UTF-8?q?rrassing=20:(=20Apologies.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One always expects a few typos to get through, a “must” or two instead of “shall”, etc., but the first commit was littered with the detritus of an incrementally developed document – a very poor show, no excuses just apologies. This commit hopefully removes the distraction of the detritus making reviewing a lot easier! Thanks especially for the Herculean efforts of Rex & Jon, anything remaining is down to me of course. --- standard/arrays.md | 2 +- standard/expressions.md | 30 +++---- standard/ranges.md | 151 ++++++++++++++++++----------------- standard/standard-library.md | 6 +- 4 files changed, 97 insertions(+), 92 deletions(-) diff --git a/standard/arrays.md b/standard/arrays.md index c42b8fadd..c1e2d66ca 100644 --- a/standard/arrays.md +++ b/standard/arrays.md @@ -114,7 +114,7 @@ Elements of arrays created by *array_creation_expression*s are always initialize Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference (§9.5) to the array element selected by the indices. -Array elements of single-dimensional arrays, can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to it, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to it, then the result of the element access is a new array formed from a shallow copy of the array elements with indicies in the `Range` value, maintaining the element order. +Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to it, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to it, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range` value, maintaining the element order. The elements of an array can be enumerated using a `foreach` statement ([§13.9.5](statements.md#1395-the-foreach-statement)). diff --git a/standard/expressions.md b/standard/expressions.md index a9357b151..6df1000b7 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2248,7 +2248,7 @@ The number of expressions in the *argument_list* shall be the same as the rank o - of type `int`, `uint`, `long`, or `ulong`; or - for single rank array access only of compile-time type `Index` or `Range`; or -- shall be implicitly convertible to one or more of the above types. +- be implicitly convertible to one or more of the above types. Indexing a single rank array using an expression of type `Index` or `Range` is *not* supported if the access is dynamically-bound (§12.8.12.1). @@ -2262,11 +2262,11 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p - The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. - If the preceding steps have produced a single index value of type `Range` then: - The result of evaluating the array access is a new array. - - The starting and ending indicies of the `Range` value are determined with respect to the length of the array referenced by `P`. + - The starting and ending indices of the `Range` value are determined with respect to the length of the array referenced by `P`. - If either index is out of range of the bounds of the array referenced by `P`, or the ending index comes before the starting index, then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. - - A new array is created from a shallow copy of the elements of `P` from the starting to ending indicies, this is commonly referred to as a *slice*. This array becomes the results of the array access. + - A new array is created from a shallow copy of the elements of `P` from the starting to ending indices, this is commonly referred to as a *slice*. This array becomes the results of the array access. -> > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses (§12.8.12.3) which may, but need not, support assignment to a range of indicies specified by a `Range` value. *end note* +> > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses (§12.8.12.3) which may, but need not, support assignment to a range of indices specified by a `Range` value. *end note* - Otherwise: - The result of evaluating the array access is a variable reference (§9.5) of the element type of the array. @@ -2275,11 +2275,11 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p #### §string-access String access -For a string access the *argument_list* of an string access shall contain a single unnamed value argument (§15.6.2.2) which shall be of type: +For a string access the *argument_list* of an string access shall contain a single unnamed value argument (§15.6.2.2) which shall be: - of type `int`; or - of compile-time type `Index` or `Range`; or -- shall be implicitly convertible to one or more of the above types. +- implicitly convertible to one or more of the above types. Indexing a string using an expression of type `Index` or `Range` is *not* supported if the access is dynamically-bound (§12.8.12.1). @@ -2292,9 +2292,9 @@ The run-time processing of a string access of the form `P[A]`, where `P` is a *p - The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. - If the preceding steps have produced an index value of type `Range` then: - The result of evaluating the string access is a value of `string` type. - - The starting and ending indicies of the `Range` value are determined with respect to the length of the string referenced by `P`. + - The starting and ending indices of the `Range` value are determined with respect to the length of the string referenced by `P`. - If either index is out of range of the bounds of the string referenced by `P`, or the ending index comes before the starting index, then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. - - The result of the string access is a new string formed from a shallow copy of the characters of `P` from the starting to ending indicies, this is commonly referred to as a *substring*. + - The result of the string access is a new string formed from a shallow copy of the characters of `P` from the starting to ending indices, this is commonly referred to as a *substring*. - Otherwise: - The result of evaluating the string access is a value of `char` type. - The value of the converted index expression is checked against the actual bounds of the string instance referenced by `P`. If the value is out of range, a `System.IndexOutOfRangeException` is thrown and no further steps are executed. @@ -2302,7 +2302,7 @@ The run-time processing of a string access of the form `P[A]`, where `P` is a *p #### 12.8.12.3 Indexer access -For an indexer access, the *primary_expression* of the *element_access* shall be a variable or value of a class, struct, or interface type, and this type shall implement one or more indexers that are applicable with respect to the *argument_list* of the *element_access*. The *argument_list* cannot contain `out` or `ref` arguments. +For an indexer access, the *primary_expression* of the *element_access* shall be a variable or value of a class, struct, or interface type, and this type shall implement one or more indexers that are applicable with respect to the *argument_list* of the *element_access*. The *argument_list* shall not cannot contain `out` or `ref` arguments. The binding-time processing of an indexer access of the form `P[A]`, where `P` is a *primary_expression* of a class, struct, or interface type `T`, and `A` is an *argument_list*, consists of the following steps: @@ -2313,9 +2313,9 @@ The binding-time processing of an indexer access of the form `P[A]`, where `P` i - If `I` is applicable with respect to `A` ([§12.6.4.2](expressions.md#12642-applicable-function-member)) and `S` is a class type other than `object`, all indexers declared in an interface are removed from the set. - If the resulting set of candidate indexers is empty, then no applicable indexers exist, and a binding-time error occurs. - The best indexer of the set of candidate indexers is identified using the overload resolution rules of [§12.6.4](expressions.md#1264-overload-resolution). If a single best indexer cannot be identified, the indexer access is ambiguous, and a binding-time error occurs. -- The accesors of the best indexer are checked: - - If the indexer access is the target of an assignment then the indexer must have a set or ref get accessor, if not a binding-time error occurs; - - Otherwise the indexer must have a get or ref get accesor, if not a binding-time arror occurs. +- The accessors of the best indexer are checked: + - If the indexer access is the target of an assignment then the indexer shall have a set or ref get accessor, if not a binding-time error occurs; + - Otherwise the indexer shall have a get or ref get accessor, otherwise a binding-time error occurs. The runtime processing of the indexer access consits of the following steps: @@ -2323,7 +2323,7 @@ The runtime processing of the indexer access consits of the following steps: - The index expressions of the *argument_list* `A` are evaluated in order, from left to right. - Using the best indexer determined at binding-time: - If the indexer access is the target of an assignment, the set accessor or ref get accessor is invoked to assign a new value ([§12.21.2](expressions.md#12212-simple-assignment)). - - In all other cases, the get accessor or ref get accesor is invoked to obtain the current value ([§12.2.2](expressions.md#1222-values-of-expressions)). + - In all other cases, the get accessor or ref get accessor is invoked to obtain the current value ([§12.2.2](expressions.md#1222-values-of-expressions)). The result of processing the indexer access is an expression classified as an indexer access. @@ -3662,7 +3662,7 @@ Index operator ^(int x); The hat operator is not overloadable (§12.4.3). -The result of an operation of the form `^x` is a from-end `Index` value (§24.2) equivalent to the result of the expression: +The result of an operation of the form `^x` is a from-end `Index` (§24.2) value equivalent to the result of the expression: ```csharp new Index(x, true) @@ -3827,7 +3827,7 @@ All range expressions are treated as having the form `x..y`, where: - `x` is the left operand if present, otherwise the expression `0`; and - `y` is the right operand if present, otherwise the expression `^0`. -The result of the operation is a `Range` value (§24.3) equivalent to the result of the expression: +The result of the operation is a `Range` (§24.3) value equivalent to the result of the expression: ```csharp new Range(x, y) diff --git a/standard/ranges.md b/standard/ranges.md index af9a61630..e52336389 100644 --- a/standard/ranges.md +++ b/standard/ranges.md @@ -1,12 +1,12 @@ # 24 Extended Indexing and Slicing -> **Review Note:** This new chapter, currently (§24), is placed here temporarily to avoid text changes due to renumbering occurring in chapters & clauses otherwise unaffected by the PR. It’s final placement is not yet determined, however between the Arrays ([§17](arrays.md#17-arrays)) and Interfaces ([§18](interfaces.md#18-interfaces)) chapters might be suitable – other placements can be suggested during review. It can be relocated later with just a simple edit to `clauses.json`. +> **Review Note:** This new clause, currently (§24), is placed here temporarily to avoid text changes due to renumbering occurring in chapters & clauses otherwise unaffected by the PR. Its final placement is not yet determined, however between the Arrays ([§17](arrays.md#17-arrays)) and Interfaces ([§18](interfaces.md#18-interfaces)) chapters might be suitable – other placements can be suggested during review. It can be relocated later with just a simple edit to `clauses.json`. ## 24.1 General -This chapter introduces a model for *extended indexable* and *sliceable* *collection* types built on: +This clause introduces a model for *extended indexable* and *sliceable* *collection* types built on: -- The types introduced in this chapter, `System.Index` (§24.2) and `System.Range` (§24.3); +- The types introduced in this clause, `System.Index` (§24.2) and `System.Range` (§24.3); - The pre-defined unary `^` (§hat-operator) and binary `..` (§range-operator) operators; and - The *element_access* expression. @@ -14,7 +14,7 @@ Under the model a type is classified as: - a *collection* if it represents a group of *element*s - an *extended indexable* collection if it supports an *element_access* expression which has a single argument expression of type `Index` which returns and/or sets a single element of the type, either by value or by reference; and -- an *extended sliceable* if it supports an *element_access* expression which has a single argument expression of type `Range` which returns a *slice* of the elements of the type by value. +- an *extended sliceable* collection if it supports an *element_access* expression which has a single argument expression of type `Range` which returns a *slice* of the elements of the type by value. > *Note*: The model does not require that a slice, unlike an element, of the type can be set, but a type may support it as an extension of the model. *end note* @@ -24,23 +24,21 @@ The model can be supported by any class, struct or interface type which provides Implicit support for the model is provided for types which do not directly support it but which provide a certain *pattern* of members (§24.4). This support is pattern-based, rather than semantic-based, as the semantics of the type members upon which it is based are *assumed* – the language does not enforce, or check, the semantics of these type members. -### 24.1.1 Definitions +For the purposes of this clause the following terms are defined: -For the purposes of this chapter the following terms are defined: - -- A ***collection*** is a type which represents a group of ***element***s -- A ***countable*** collection is one which provides a ***countable property*** an `int` valued instance property whose value is the number of elements currently in the group. This property must be named either `Length` or `Count`, the former is chosen if both exist. -- A ***sequence*** or ***indexable*** type is a collection: +- A ***collection*** is a type which represents a group of ***element***s. +- A ***countable collection*** is one which provides a ***countable property*** an `int` valued instance property whose value is the number of elements currently in the group. This property shall be named either `Length` or `Count`, the former is chosen if both exist. +- A ***sequence*** or ***indexable type*** is a collection: - which is countable; - where every element can be accessed using an *element_access* expression with a single required `int` argument, the ***from-start index***, additional optional arguments are allowed; - a sequence is ***modifiable*** if every element can also be set using an *element_access* expression; - an element’s from-start index is the number of elements before it in the sequence, for a sequence containing *N* elements: - - the first and last elements have indicies of 0 and *N*-1 respectively, and - - the ***past-end*** index, an index which represents a hypothetical element after the last one, has the value *N*; -- A ***from-end index*** represents an element’s position within a sequence relative to the last element. For a sequence containing *N* elements the first, last and past-end indicies are *N*, 1 and 0 respectively. -- A ***range*** is a contiguous run of zero or more indicies starting at any index within a sequence. + - the first and last elements have indices of 0 and *N*-1 respectively, and + - the ***past-end index***, an index which represents a hypothetical element after the last one, has the value *N*. +- A ***from-end index*** represents an element’s position within a sequence relative to the last element. For a sequence containing *N* elements the first, last and past-end indices are *N*, 1 and 0 respectively. +- A ***range*** is a contiguous run of zero or more indices starting at any index within a sequence. - A ***slice*** is the collection of elements within a range. -- A ***sliceable*** collection is one which: +- A ***sliceable collection*** is one which: - is countable; - provides a method `Slice` which takes two `int` parameters specifying a range, being a starting index and a count of elements respectively, and returns a new slice constructed from the elements in the range. @@ -57,7 +55,7 @@ The required members for a type to qualify as a sequence or sliceable may be inh > *Example*: In the following code > -> ```CSharp +> ```csharp > public class A > { > public int Length { get { … } } @@ -77,20 +75,22 @@ The required members for a type to qualify as a sequence or sliceable may be inh > The type `A` is countable, `B` is a sequence, and `C` is sliceable and a sequence. > > *end example* + -*Note*: - -- A type can be sliceable without being indexable due to the lack of an (accessible) indexer. -- For a type to be sliceable and/or indexable requires the type to be countable. -- While the elements of a sequence are ordered by *position* within the sequence the elements themselves need not be ordered by their value, or even orderable. - -*end note* + +> *Note*: +> +> - A type can be sliceable without being indexable due to the lack of an (accessible) indexer. +> - For a type to be sliceable and/or indexable requires the type to be countable. +> - While the elements of a sequence are ordered by *position* within the sequence the elements themselves need not be ordered by their value, or even orderable. +> +> *end note* -## 24.2 The `Index` type +## 24.2 The Index type The `System.Index` type represents an *abstract* index which is either a *from-start index* or a *from-end index*. -```CSharp +```csharp public readonly struct Index : IEquatable { public int Value { get; } @@ -104,11 +104,11 @@ The `System.Index` type represents an *abstract* index which is either a *from-s } ``` -`Index` values are constructed from an `int`, specifying the positive offset, and a `bool`, indicating whether the offset is from the end (`true`) or start (`false`). If the specified offset is negative an `ArgumentOutOfRangeException` is thrown. +`Index` values are constructed from an `int`, specifying the non-negative offset, and a `bool`, indicating whether the offset is from the end (`true`) or start (`false`). If the specified offset is negative an `ArgumentOutOfRangeException` is thrown. > *Example* > -> ```CSharp +> ```csharp > Index first = new Index(0, false); // first element index > var last = new Index(1, true); // last element index > var past = new Index(0, true); // past-end index @@ -118,13 +118,13 @@ The `System.Index` type represents an *abstract* index which is either a *from-s > > *end example* -There is an implicit conversion from `int` to `Index` which produces from-start indicies, and a language-defined unary operator `^` (§hat-operator) from `int` to `Index` which produces from-end indicies. +There is an implicit conversion from `int` to `Index` which produces from-start indices, and a language-defined unary operator `^` (§hat-operator) from `int` to `Index` which produces from-end indices. > *Example* > > Using implicit conversions and the unary `^` operator the above examples may be written: > -> ```CSharp +> ```csharp > Index first = 0; // first element index > var last = ^1; // last element index > var past = ^0; // past-end index @@ -132,9 +132,7 @@ There is an implicit conversion from `int` to `Index` which produces from-start > > *end example* -The method `GetOffset` converts from an abstract `Index` value to a concrete `int` index value for a sequence of the specified `length`. - -If the `Index` value, `I`, is from-end this method returns the same value as `length - I.Value`, otherwise it returns the same value as `I.Value`. +The method `GetOffset` converts from an abstract `Index` value to a concrete `int` index value for a sequence of the specified `length`. If the `Index` value, `I`, is from-end this method returns the same value as `length - I.Value`, otherwise it returns the same value as `I.Value`. This method does **not** check that the return value is in the valid range of `0` through `length-1` inclusive. @@ -142,22 +140,22 @@ This method does **not** check that the return value is in the valid range of `0 `Index` implements `IEquatable` and values may be compared for equality. However `Index` values are not ordered and no other comparison operations are provided. -> *Note:* `Index` values are unordered as they are abstract indicies, it is in general impossible to determine whether a from-end index comes before or after a from start index without reference to a sequence length. Once converted to concrete indicies, e.g. by `GetOffset`, those concrete indicies are comparable. *end note* +> *Note:* `Index` values are unordered as they are abstract indices, it is in general impossible to determine whether a from-end index comes before or after a from start index without reference to a sequence length. Once converted to concrete indices, e.g. by `GetOffset`, those concrete indices are comparable. *end note* `Index` values may be directly used in the *argument_list* of an *element_access* expression (§12.8.12): -- which is statically bound (§12.3.2) and: - - it is an array access and the target is a single-dimensional array (§12.8.12.2); - - it is a string access (§string-access); or - - it is an indexer access and the target type conforms to a sequence pattern for which implicit `Index` support is specified (§24.4.2). -- which is statically or dynamically bound (§12.3.2) and: - - it is an indexer access and the target type has an indexer with parameters of `Index` type (§12.8.12.3); +- which is statically bound (§12.3.2) and is: + - an array access and the target is a single-dimensional array (§12.8.12.2); + - a string access (§string-access); or + - an indexer access and the target type conforms to a sequence pattern for which implicit `Index` support is specified (§24.4.2). +- which is statically or dynamically bound (§12.3.2) and is: + - an indexer access and the target type has an indexer with parameters of `Index` type (§12.8.12.3); -## 24.3 The `Range` type +## 24.3 The Range type The `System.Range` type represents the abstract range of `Index`es from a `Start` index up to, but not including, an `End` index. -```CSharp +```csharp public readonly struct Range : IEquatable { public Index Start { get; } @@ -174,16 +172,18 @@ The `System.Range` type represents the abstract range of `Index`es from a `Start > *Example* > -> The following examples use the implicit conversion from `int` to `Index` (introduced above) and the `^` (§hat-operator) operator to create the `Index` values for each `Range`: +> The following examples use the implicit conversion from `int` to `Index` (§24.2) and the `^` (§hat-operator) operator to create the `Index` values for each `Range`: > -> ```CSharp -> var firstQuad = new Range(0, 4); // the indicies from `0` to `3` +> ```csharp +> var firstQuad = new Range(0, 4); // the indices from `0` to `3` > // int values impicitly convert to `Index` -> var nextQuad = new Range(4, 8); // the indicies from `4` to `7` -> var wholeSeq = new Range(0, ^0); // the indicies from `0` to `N-1` where `N` is the +> var nextQuad = new Range(4, 8); // the indices from `4` to `7` +> var wholeSeq = new Range(0, ^0); // the indices from `0` to `N-1` where `N` is the > // length of the sequence wholeSeq is used with -> var dropFirst = new Range(1, ^0); // the indicies from `1` to `N-1` -> var dropLast = new Range(0, ^1); // the indicies from `0` to `N-2` +> var dropFirst = new Range(1, ^0); // the indices from `1` to `N-1` +> var dropLast = new Range(0, ^1); // the indices from `0` to `N-2` +> var maybeLast = new Range(^1, 6); // the indices from `N-1` to 5 +> var lastTwo = new Range(^2, ^0); // the indices from `N-2` to `N-1` > ``` > > *end example* @@ -194,12 +194,14 @@ The language-defined operator `..` (§range-operator) creates a `Range` value fr > > Using the `..` the above examples may be written: > -> ```CSharp -> var firstQuad = 0..4; // the indicies from `0` to `3` -> var nextQuad = 4..8; // the indicies from `4` to `7` -> var wholeSeq = 0..^0; // the indicies from `0` to `N-1` -> var dropFirst = 1..^0; // the indicies from `1` to `N-1` -> var dropLast = 0..^1; // the indicies from `0` to `N-2` +> ```csharp +> var firstQuad = 0..4; // the indices from `0` to `3` +> var nextQuad = 4..8; // the indices from `4` to `7` +> var wholeSeq = 0..^0; // the indices from `0` to `N-1` +> var dropFirst = 1..^0; // the indices from `1` to `N-1` +> var dropLast = 0..^1; // the indices from `0` to `N-2` +> var maybeLast = ^1..6; // the indices from `N-1` to 5 +> var lastTwo = ^2..^0; // the indices from `N-2` to `N-1` > ``` > > *end example* @@ -208,13 +210,14 @@ The operands of `..` are optional, the first defaults to `0`, the second default > *Example* > -> Four of the above examples can also be written: +> Five of the above examples can also be written: > -> ```CSharp -> var firstQuad = ..4; // the indicies from `0` to `3` -> var wholeSeq = ..; // the indicies from `0` to `N-1` -> var dropFirst = 1..; // the indicies from `1` to `N-1` -> var dropLast = ..^1; // the indicies from `0` to `N-2` +> ```csharp +> var firstQuad = ..4; // the indices from `0` to `3` +> var wholeSeq = ..; // the indices from `0` to `N-1` +> var dropFirst = 1..; // the indices from `1` to `N-1` +> var dropLast = ..^1; // the indices from `0` to `N-2` +> var lastTwo = ^2..; // the indices from `N-2` to `N-1` > ``` > > *end example* @@ -225,29 +228,31 @@ The method `GetOffsetAndLength` converts an abstract `Range` value to a tuple va > > Using the variables defined above with `GetOffSetAndLength(6)`: > -> ```CSharp +> ```csharp > var (ix0, len0) = firstQuad.GetOffsetAndLength(6); // ix0 = 0, len0 = 4 > var (ix1, len1) = nextQuad.GetOffsetAndLength(6); // throws ArgumentOutOfRangeException > // as range crosses sequence end > var (ix2, len2) = wholeSeq.GetOffsetAndLength(6); // ix2 = 0, len2 = 6 > var (ix3, len3) = dropFirst.GetOffsetAndLength(6); // ix3 = 1, len3 = 5 > var (ix4, len4) = dropLast.GetOffsetAndLength(6); // ix4 = 0, len4 = 5 +> var (ix5, len5) = maybeLast.GetOffsetAndLength(6); // ix5 = 5, len5 = 1 +> var (ix6, len6) = lastTwo.GetOffsetAndLength(6); // ix6 = 4, len6 = 2 > ``` `Range` implements `IEquatable` and values may be compared for equality. However `Range` values are not ordered and no other comparison operations are provided. -> *Note:* `Range` values are unordered both as they are abstract and there is no unique ordering relation. Once converted to a concrete start and length, e.g. by `GetOffsetAndLength`, and ordering relation could be defined. *end note* +> *Note:* `Range` values are unordered both as they are abstract and there is no unique ordering relation. Once converted to a concrete start and length, e.g. by `GetOffsetAndLength`, an ordering relation could be defined. *end note* `Range` values can be directly used in the *argument_list* of an *element_access* expression (§12.8.12): -- which is statically bound (§12.3.2) and: - - it is an array access and the target is a single-dimensional array (§12.8.12.2); - - it is a string access (§string-access); or - - it is an indexer access (§12.8.12.3) and the target type conforms to a sequence pattern for which implicit `Range` support is specified (§24.4.3). -- which is statically or dynamically bound (§12.3.2) and: - - it is an indexer access and the target type has an indexer with parameters of `Range` type (§12.8.12.3). +- which is statically bound (§12.3.2) and is: + - an array access and the target is a single-dimensional array (§12.8.12.2); + - a string access (§string-access); or + - an indexer access (§12.8.12.3) and the target type conforms to a sequence pattern for which implicit `Range` support is specified (§24.4.3). +- which is statically or dynamically bound (§12.3.2) and is: + - an indexer access and the target type has an indexer with parameters of `Range` type (§12.8.12.3). -## 24.4 Pattern-based implicit support for `Index` and `Range` +## 24.4 Pattern-based implicit support for Index and Range ### 24.4.1 General @@ -255,16 +260,16 @@ If a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12. - an array access (§12.8.12.2), - a string access (§string-access), or -- or and indexer access (§12.8.12.3) as `T` provides no suitable accessible indexer +- an indexer access (§12.8.12.3) as `T` provides no suitable accessible indexer then pattern-based implicit support for the expression is provided if `T` conforms to a pattern. If `T` does not conform to the pattern then a compile-time error occurs. -### 24.4.2 Implicit `Index` Support +### 24.4.2 Implicit Index support If in any context a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index`; is not valid (§24.4.1) then if in the same context: - `T` provides accessible members qualifying it as a *sequence* (§24.1.1); and -- the expression `E[0]` is valid +- the expression `E[0]` is valid and uses the indexer qualifying `T` as a sequence then the expression `E[A]` shall be implicitly supported. @@ -275,7 +280,7 @@ Without otherwise constraining implementations of this Standard the order of eva 3. the countable property of `T` is evaluated, if required by the implementation; 4. the get or set accessor of the `int` based indexer of `T` that would be used by `E[0]` in the same context is invoked. -### 24.4.3 Implicit `Range` Support +### 24.4.3 Implicit Range support If in any context a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid (§24.4.1) then if in the same context: diff --git a/standard/standard-library.md b/standard/standard-library.md index a3b1aced6..fc0dc2b44 100644 --- a/standard/standard-library.md +++ b/standard/standard-library.md @@ -416,7 +416,7 @@ namespace System /// from-start index to be used with a collection /// of some specified length. /// - Equality between Index values is provided, however - /// unlike concrete indicies they are not ordered. + /// unlike concrete indices they are not ordered. /// - Array and String element access support indexing /// with Index values. /// @@ -498,7 +498,7 @@ namespace System /// /// A read-only value type which represents a range of - /// abstract indicies to be used with collections. + /// abstract indices to be used with collections. /// - The Range has two Index properties, Start and End. /// - A Range can be converted to a concrete index from /// the start and a length value to be used with a @@ -523,7 +523,7 @@ namespace System /// of the range. /// /// As Index values represent unordered abstract - /// indicies no sanity checking can be performed + /// indices no sanity checking can be performed /// on the resultant Range value, /// ". /// From 72930dc2c8ae3db2a08707d9972ad97dfb960715 Mon Sep 17 00:00:00 2001 From: Nigel-Ecma Date: Wed, 30 Jul 2025 14:53:18 +1200 Subject: [PATCH 3/8] Fix spelling (not all down to this PR, Engish/American disagreements left untouched); other reported nits; and the numbering oops (24.1.1 -> 24.1 as header was removed) --- standard/expressions.md | 18 +++++++++--------- standard/ranges.md | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index 6df1000b7..d3d500997 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -1732,7 +1732,7 @@ In a member access of the form `E.I`, if `E` is a single identifier, and if the A *null_conditional_member_access* is a conditional version of *member_access* ([§12.8.7](expressions.md#1287-member-access)) and it is a binding time error if the result type is `void`. For a null conditional expression where the result type may be `void` see ([§12.8.11](expressions.md#12811-null-conditional-invocation-expression)). -A *null_conditional_member_access* consists of a *primary_expression* followed by the two tokens “`?`” and “`.`”, followed by an *identifier* with an optional *type_argument_list*, followed by zero or more *dependent_access*es any of which can be preceeded by a *null_forgiving_operator*. +A *null_conditional_member_access* consists of a *primary_expression* followed by the two tokens “`?`” and “`.`”, followed by an *identifier* with an optional *type_argument_list*, followed by zero or more *dependent_access*es any of which can be preceded by a *null_forgiving_operator*. ```ANTLR null_conditional_member_access @@ -1822,7 +1822,7 @@ null_forgiving_operator ; ``` -*Note*: The postfix null-forgiving and prefix logical negation operators ([§12.9.4](expressions.md#1294-logical-negation-operator)), while represented by the same lexical token (`!`), are distinct. Only the latter may be overriden ([§15.10](classes.md#1510-operators)), the definition of the null-forgiving operator is fixed. *end note* +*Note*: The postfix null-forgiving and prefix logical negation operators ([§12.9.4](expressions.md#1294-logical-negation-operator)), while represented by the same lexical token (`!`), are distinct. Only the latter may be overridden ([§15.10](classes.md#1510-operators)), the definition of the null-forgiving operator is fixed. *end note* It is a compile-time error to apply the null-forgiving operator more than once to the same expression, intervening parentheses notwithstanding. @@ -2117,7 +2117,7 @@ The preceding rules mean that instance methods take precedence over extension me > C.H(3) > ``` > -> `D.G` takes precendece over `C.G`, and `E.F` takes precedence over both `D.F` and `C.F`. +> `D.G` takes precedence over `C.G`, and `E.F` takes precedence over both `D.F` and `C.F`. > > *end example* @@ -2156,7 +2156,7 @@ in terms of what is included the text will probably be fine but this will need t The optional *null_forgiving_operator* may be included if and only if the *null_conditional_member_access* or *null_conditional_element_access* has a *delegate_type*. -A *null_conditional_invocation_expression* expression `E` is of the form `P?A`; where `A` is the remainder of the syntactically equivalent *null_conditional_member_access* or *null_conditional_element_access*, `A` will therefore start with `.` or `[`. Let `PA` signify the concatention of `P` and `A`. +A *null_conditional_invocation_expression* expression `E` is of the form `P?A`; where `A` is the remainder of the syntactically equivalent *null_conditional_member_access* or *null_conditional_element_access*, `A` will therefore start with `.` or `[`. Let `PA` signify the concatenation of `P` and `A`. When `E` occurs as a *statement_expression* the meaning of `E` is the same as the meaning of the *statement*: @@ -2275,7 +2275,7 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p #### §string-access String access -For a string access the *argument_list* of an string access shall contain a single unnamed value argument (§15.6.2.2) which shall be: +For a string access the *argument_list* of the *element_access* shall contain a single unnamed value argument (§15.6.2.2) which shall be: - of type `int`; or - of compile-time type `Index` or `Range`; or @@ -2317,7 +2317,7 @@ The binding-time processing of an indexer access of the form `P[A]`, where `P` i - If the indexer access is the target of an assignment then the indexer shall have a set or ref get accessor, if not a binding-time error occurs; - Otherwise the indexer shall have a get or ref get accessor, otherwise a binding-time error occurs. -The runtime processing of the indexer access consits of the following steps: +The runtime processing of the indexer access consists of the following steps: - The target *primary_expression* `P` is evaluated. - The index expressions of the *argument_list* `A` are evaluated in order, from left to right. @@ -4707,7 +4707,7 @@ User defined conversions are not considered by the `is` operator. > - If the compile-time type of `e` is the same as `T`, or if an implicit reference conversion ([§10.2.8](conversions.md#1028-implicit-reference-conversions)), boxing conversion ([§10.2.9](conversions.md#1029-boxing-conversions)), wrapping conversion ([§10.6](conversions.md#106-conversions-involving-nullable-types)), or an explicit unwrapping conversion ([§10.6](conversions.md#106-conversions-involving-nullable-types)) exists from the compile-time type of `E` to `T`: > - If `C` is of a non-nullable value type, the result of the operation is `true`. > - Otherwise, the result of the operation is equivalent to evaluating `E != null`. -> - Otherwise, if an explicit reference conversion ([§10.3.5](conversions.md#1035-explicit-reference-conversions)) or unboxing conversion ([§10.3.7](conversions.md#1037-unboxing-conversions)) exists from `C` to `T`, or if `C` or `T` is an open type ([§8.4.3](types.md#843-open-and-closed-types)), then runtime checks as above shall be peformed. +> - Otherwise, if an explicit reference conversion ([§10.3.5](conversions.md#1035-explicit-reference-conversions)) or unboxing conversion ([§10.3.7](conversions.md#1037-unboxing-conversions)) exists from `C` to `T`, or if `C` or `T` is an open type ([§8.4.3](types.md#843-open-and-closed-types)), then runtime checks as above shall be performed. > - Otherwise, no reference, boxing, wrapping, or unwrapping conversion of `E` to type `T` is possible, and the result of the operation is `false`. > A compiler may implement optimisations based on the compile-time type. > @@ -5451,7 +5451,7 @@ A local variable is considered to be ***instantiated*** when execution enters th > > *end example* -When not captured, there is no way to observe exactly how often a local variable is instantiated—because the lifetimes of the instantiations are disjoint, it is possible for each instantation to simply use the same storage location. However, when an anonymous function captures a local variable, the effects of instantiation become apparent. +When not captured, there is no way to observe exactly how often a local variable is instantiated—because the lifetimes of the instantiations are disjoint, it is possible for each instantiation to simply use the same storage location. However, when an anonymous function captures a local variable, the effects of instantiation become apparent. > *Example*: The example > @@ -6549,7 +6549,7 @@ In the translation steps described above, transparent identifiers are always int The ***Query-expression pattern*** establishes a pattern of methods that types can implement to support query expressions. -A generic type `C` supports the query-expression-pattern if its public member methods and the publicly accessible extension methods could be replaced by the following class definition. The members and accessible extenson methods is referred to as the “shape” of a generic type `C`. A generic type is used in order to illustrate the proper relationships between parameter and return types, but it is possible to implement the pattern for non-generic types as well. +A generic type `C` supports the query-expression-pattern if its public member methods and the publicly accessible extension methods could be replaced by the following class definition. The members and accessible extension methods is referred to as the “shape” of a generic type `C`. A generic type is used in order to illustrate the proper relationships between parameter and return types, but it is possible to implement the pattern for non-generic types as well. ```csharp diff --git a/standard/ranges.md b/standard/ranges.md index e52336389..2a31e19e1 100644 --- a/standard/ranges.md +++ b/standard/ranges.md @@ -192,7 +192,7 @@ The language-defined operator `..` (§range-operator) creates a `Range` value fr > *Example* > -> Using the `..` the above examples may be written: +> Using the `..` operator the above examples may be written: > > ```csharp > var firstQuad = 0..4; // the indices from `0` to `3` @@ -268,7 +268,7 @@ then pattern-based implicit support for the expression is provided if `T` confor If in any context a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index`; is not valid (§24.4.1) then if in the same context: -- `T` provides accessible members qualifying it as a *sequence* (§24.1.1); and +- `T` provides accessible members qualifying it as a *sequence* (§24.1); and - the expression `E[0]` is valid and uses the indexer qualifying `T` as a sequence then the expression `E[A]` shall be implicitly supported. @@ -284,7 +284,7 @@ Without otherwise constraining implementations of this Standard the order of eva If in any context a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid (§24.4.1) then if in the same context: -- `T` provides accessible members qualifying it as both *countable* and *sliceable* (§24.1.1) +- `T` provides accessible members qualifying it as both *countable* and *sliceable* (§24.1) then the expression `E[A]` shall be implicitly supported. From fb1675f4eea9824a0cdd16a287a541054f8b6a1b Mon Sep 17 00:00:00 2001 From: Nigel-Ecma Date: Fri, 8 Aug 2025 15:07:04 +1200 Subject: [PATCH 4/8] Updates: - Description of the semantics of `Range` expanded in ranges.md and uses in expressions.md xref to there for the semantics - All references to certain introduced features not being available in dynamic bound code elided. - Various wording tweaks. --- standard/arrays.md | 2 +- standard/expressions.md | 49 +++++++++++++++++----------------- standard/ranges.md | 59 +++++++++++++++++++++++++---------------- 3 files changed, 61 insertions(+), 49 deletions(-) diff --git a/standard/arrays.md b/standard/arrays.md index c1e2d66ca..1fda69889 100644 --- a/standard/arrays.md +++ b/standard/arrays.md @@ -114,7 +114,7 @@ Elements of arrays created by *array_creation_expression*s are always initialize Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference (§9.5) to the array element selected by the indices. -Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to it, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to it, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range` value, maintaining the element order. +Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to it, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to it, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range`, maintaining the element order. The elements of an array can be enumerated using a `foreach` statement ([§13.9.5](statements.md#1395-the-foreach-statement)). diff --git a/standard/expressions.md b/standard/expressions.md index d3d500997..6a62a93e5 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -172,8 +172,8 @@ When an operand occurs between two operators with the same precedence, the ***as > *Example*: `x + y + z` is evaluated as `(x + y) + z`. *end example* - The assignment operators, the null coalescing operator and the conditional operator (`?:`) are ***right-associative***, meaning that operations are performed from right to left. > *Example*: `x = y = z` is evaluated as `x = (y = z)`. *end example* -- The range operator is ***non-associative***. - > *Example*: `x..y..z` is invalid. *end example* +- The range operator is ***non-associative***, meaning that neither the left nor right operand of a range operator may be a *range_expression*. + > *Example*: Both `x..y..z` and `x..(y..z)` are invalid as `..` is non-associative. *end example* Precedence and associativity can be controlled using parentheses. @@ -2247,26 +2247,28 @@ For an array access the *argument_list* shall not contain named arguments or by- The number of expressions in the *argument_list* shall be the same as the rank of the *array_type*, and each expression shall be: - of type `int`, `uint`, `long`, or `ulong`; or -- for single rank array access only of compile-time type `Index` or `Range`; or +- for single rank array access only, of type `Index` or `Range`; or - be implicitly convertible to one or more of the above types. -Indexing a single rank array using an expression of type `Index` or `Range` is *not* supported if the access is dynamically-bound (§12.8.12.1). - The run-time processing of an array access of the form `P[A]`, where `P` is a *primary_expression* of an *array_type* and `A` is an *argument_list* of index expressions, consists of the following steps: - `P` is evaluated. If this evaluation causes an exception, no further steps are executed. - For each index expression in the *argument_list* in order, from left to right: - The index expression is evaluated, let the type of the resultant value be *T*; - - This value is then converted to the first of the types: `int`, `uint`, `long`, `ulong`, or for static bound single rank array access only `Index` or `Range`; for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) from *T* exists. + - This value is then converted to the first of the types: `int`, `uint`, `long`, `ulong`, or for single rank array access only, `Index` or `Range`; for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) from *T* exists. - If evaluation of an index expression or the subsequent implicit conversion causes an exception, then no further index expressions are evaluated and no further steps are executed. - The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. - If the preceding steps have produced a single index value of type `Range` then: - - The result of evaluating the array access is a new array. - - The starting and ending indices of the `Range` value are determined with respect to the length of the array referenced by `P`. - - If either index is out of range of the bounds of the array referenced by `P`, or the ending index comes before the starting index, then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. - - A new array is created from a shallow copy of the elements of `P` from the starting to ending indices, this is commonly referred to as a *slice*. This array becomes the results of the array access. + - Let *L* be the length of the array referenced by `P`. + - `A` is checked to be valid with respect to *L* (§24.3), if it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. + - The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` (§24.3). + - A new array is created from a shallow copy of the *N* elements of `P` starting at index *S*, if *N* is zero the new array has zero elements. This array becomes the result of the array access. -> > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses (§12.8.12.3) which may, but need not, support assignment to a range of indices specified by a `Range` value. *end note* +> > > *Note:* Both *S* and *N* may be zero ($24.3). Indexing an empty array is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty array. The defintion also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty array returned. *end note* + + + +> > > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses (§12.8.12.3) which may, but need not, support assignment to a range of indices specified by a `Range` value. *end note* - Otherwise: - The result of evaluating the array access is a variable reference (§9.5) of the element type of the array. @@ -2277,24 +2279,25 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p For a string access the *argument_list* of the *element_access* shall contain a single unnamed value argument (§15.6.2.2) which shall be: -- of type `int`; or -- of compile-time type `Index` or `Range`; or +- of type `int`, `Index` or `Range`; or - implicitly convertible to one or more of the above types. -Indexing a string using an expression of type `Index` or `Range` is *not* supported if the access is dynamically-bound (§12.8.12.1). - The run-time processing of a string access of the form `P[A]`, where `P` is a *primary_expression* of `string` type and `A` is a single expression, consists of the following steps: - `P` is evaluated. If this evaluation causes an exception, no further steps are executed. - The index expression is evaluated, let the type of the resultant value be *T*; -- This value is then converted to the first of the types: `int`, or for static bound expressions only `Index` or `Range`; for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) from *T* exists. +- This value is then converted to the first of the types: `int`, `Index` or `Range`; for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) from *T* exists. - If evaluation of an index expression or the subsequent implicit conversion causes an exception, then no further index expressions are evaluated and no further steps are executed. - The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. - If the preceding steps have produced an index value of type `Range` then: - The result of evaluating the string access is a value of `string` type. - - The starting and ending indices of the `Range` value are determined with respect to the length of the string referenced by `P`. - - If either index is out of range of the bounds of the string referenced by `P`, or the ending index comes before the starting index, then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. - - The result of the string access is a new string formed from a shallow copy of the characters of `P` from the starting to ending indices, this is commonly referred to as a *substring*. + - Let *L* be the length of the string referenced by `P`. + - `A` is checked to be valid with respect to *L* (§24.3), if it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. + - The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` (§24.3). + - The result of the string access is a new string formed by copying the *N* characters of `P` starting from *S*, if *N* is zero the new string is empty. + +> > > *Note:* Both *S* and *N* may be zero (§24.3). Indexing an empty string is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty string. The defintion also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty string returned. *end note* + - Otherwise: - The result of evaluating the string access is a value of `char` type. - The value of the converted index expression is checked against the actual bounds of the string instance referenced by `P`. If the value is out of range, a `System.IndexOutOfRangeException` is thrown and no further steps are executed. @@ -2325,8 +2328,6 @@ The runtime processing of the indexer access consists of the following steps: - If the indexer access is the target of an assignment, the set accessor or ref get accessor is invoked to assign a new value ([§12.21.2](expressions.md#12212-simple-assignment)). - In all other cases, the get accessor or ref get accessor is invoked to obtain the current value ([§12.2.2](expressions.md#1222-values-of-expressions)). -The result of processing the indexer access is an expression classified as an indexer access. - ### 12.8.13 Null Conditional Element Access A *null_conditional_element_access* consists of a *primary_expression* followed by the two tokens “`?`” and “`[`”, followed by an *argument_list*, followed by a “`]`” token, followed by zero or more *dependent_access*es any of which can be preceded by a *null_forgiving_operator*. @@ -3652,16 +3653,14 @@ The result of evaluating `~x`, where `X` is an expression of an enumeration ty Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined bitwise complement operators defined above are also predefined. -### §hat-operator Hat/index from-end operator +### §hat-operator Hat operator -The unary `^` operator is called the *hat* (or *index from-end*) operator. The predefined hat operator is: +The unary `^` operator is called the *hat* operator. The hat operator is not overloadable (§12.4.3) and there is a single predefined hat operator: ```csharp Index operator ^(int x); ``` -The hat operator is not overloadable (§12.4.3). - The result of an operation of the form `^x` is a from-end `Index` (§24.2) value equivalent to the result of the expression: ```csharp diff --git a/standard/ranges.md b/standard/ranges.md index 2a31e19e1..538852b9f 100644 --- a/standard/ranges.md +++ b/standard/ranges.md @@ -138,18 +138,16 @@ This method does **not** check that the return value is in the valid range of `0 > *Note:* No checking is specified as the expected use of the result is to index into a sequence with `length` elements, and that indexing operation is expected to perform the appropriate checks. *end note* -`Index` implements `IEquatable` and values may be compared for equality. However `Index` values are not ordered and no other comparison operations are provided. +`Index` implements `IEquatable` and values may be compared for equality based on the abstract value; two `Index` values are equal if and only if the respective `Value` and `IsFromEnd` properties are equal. However `Index` values are not ordered and no other comparison operations are provided. > *Note:* `Index` values are unordered as they are abstract indices, it is in general impossible to determine whether a from-end index comes before or after a from start index without reference to a sequence length. Once converted to concrete indices, e.g. by `GetOffset`, those concrete indices are comparable. *end note* -`Index` values may be directly used in the *argument_list* of an *element_access* expression (§12.8.12): +`Index` values may be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: -- which is statically bound (§12.3.2) and is: - - an array access and the target is a single-dimensional array (§12.8.12.2); - - a string access (§string-access); or - - an indexer access and the target type conforms to a sequence pattern for which implicit `Index` support is specified (§24.4.2). -- which is statically or dynamically bound (§12.3.2) and is: - - an indexer access and the target type has an indexer with parameters of `Index` type (§12.8.12.3); +- an array access and the target is a single-dimensional array (§12.8.12.2); +- a string access (§string-access) +- an indexer access and the target type has an indexer with corresponding parameters of either `Index` type (§12.8.12.3) or of a type to which `Index` values are implicitly convertible; or +- an indexer access and the target type conforms to a sequence pattern for which implicit `Index` support is specified (§24.4.2). ## 24.3 The Range type @@ -210,7 +208,7 @@ The operands of `..` are optional, the first defaults to `0`, the second default > *Example* > -> Five of the above examples can also be written: +> Five of the above examples can be shortened by relying on default values for operands: > > ```csharp > var firstQuad = ..4; // the indices from `0` to `3` @@ -222,8 +220,25 @@ The operands of `..` are optional, the first defaults to `0`, the second default > > *end example* -The method `GetOffsetAndLength` converts an abstract `Range` value to a tuple value consisting of a concrete `int` index and a number of elements, applicable to a sequence with `length` elements. If the `Range` value is invalid with respect to sequence with `length` elements this method throws `ArgumentOutOfRangeException`. +A `Range` value is *valid* with respect to a length *L* if: +- the concrete indices with respect to *L* of the `Range` properties `Start` and `End` are in the range 0 to *L*; and +- the concrete index for `Start` is not greater than the concrete index for `End` + +The method `GetOffsetAndLength` with an argument `length` converts an abstract `Range` value to a concrete `Range` value represented by tuple. If the `Range` is not valid with respect to `length` the method throws `ArgumentOutOfRangeException`. + +The returned concrete `Range` tuple is a pair of the form `(S, N)` where: + +- `S` is the starting offset of the range, being the concrete index for the `Start` property of the `Range`; and +- `N` is the number of items in the range, being the difference between the concrete indices for the `End` and `Start` properties; +- both values being calculated with respect to `length`. + +A concrete range value is *empty* if `N` is zero. An empty concrete range may have an `S` value equal to concrete past-end index (§24.1), a non-empty range may not. When a `Range` which is used to slice (§24.1) a collection is valid and empty with respect to that collection then the resulting slice is an empty collection. + +> *Note:* A consequence of the above is that a `Range` value which is valid and empty with respect to a `length` of zero may be used to slice an empty collection and results in an empty slice. This differs from indexing which throws an exception if the collection is empty. *end note** + + + > *Example* > > Using the variables defined above with `GetOffSetAndLength(6)`: @@ -239,37 +254,35 @@ The method `GetOffsetAndLength` converts an abstract `Range` value to a tuple va > var (ix6, len6) = lastTwo.GetOffsetAndLength(6); // ix6 = 4, len6 = 2 > ``` -`Range` implements `IEquatable` and values may be compared for equality. However `Range` values are not ordered and no other comparison operations are provided. +`Range` implements `IEquatable` and values may be compared for equality based on the abstract value; two `Range` values are equal if and only if the abstract values of the respective `Start` and `End` properties are equal (§24.2). However `Range` values are not ordered and no other comparison operations are provided. > *Note:* `Range` values are unordered both as they are abstract and there is no unique ordering relation. Once converted to a concrete start and length, e.g. by `GetOffsetAndLength`, an ordering relation could be defined. *end note* -`Range` values can be directly used in the *argument_list* of an *element_access* expression (§12.8.12): +`Range` values can be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: -- which is statically bound (§12.3.2) and is: - - an array access and the target is a single-dimensional array (§12.8.12.2); - - a string access (§string-access); or - - an indexer access (§12.8.12.3) and the target type conforms to a sequence pattern for which implicit `Range` support is specified (§24.4.3). -- which is statically or dynamically bound (§12.3.2) and is: - - an indexer access and the target type has an indexer with parameters of `Range` type (§12.8.12.3). +- an array access and the target is a single-dimensional array (§12.8.12.2); +- a string access (§string-access); +- an indexer access and the target type has an indexer with corresponding parameters of either `Range` type (§12.8.12.3) or of a type to which `Range` values are implicitly convertible; or +- an indexer access (§12.8.12.3) and the target type conforms to a sequence pattern for which implicit `Range` support is specified (§24.4.3). ## 24.4 Pattern-based implicit support for Index and Range ### 24.4.1 General -If a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible at compile-time to `Index` or `Range`; fails to be identified as: +If an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index` or `Range`; fails to be identified as: - an array access (§12.8.12.2), - a string access (§string-access), or - an indexer access (§12.8.12.3) as `T` provides no suitable accessible indexer -then pattern-based implicit support for the expression is provided if `T` conforms to a pattern. If `T` does not conform to the pattern then a compile-time error occurs. +then implicit support for the expression is provided if `T` conforms to a particular pattern. If `T` does not conform to this pattern then a compile-time error occurs. ### 24.4.2 Implicit Index support -If in any context a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index`; is not valid (§24.4.1) then if in the same context: +If in any context an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index`; is not valid (§24.4.1) then if in the same context: - `T` provides accessible members qualifying it as a *sequence* (§24.1); and -- the expression `E[0]` is valid and uses the indexer qualifying `T` as a sequence +- the expression `E[0]` is valid and uses the same indexer that qualifies `T` as a sequence then the expression `E[A]` shall be implicitly supported. @@ -282,7 +295,7 @@ Without otherwise constraining implementations of this Standard the order of eva ### 24.4.3 Implicit Range support -If in any context a statically bound (§12.3.2, §12.8.12.1) *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid (§24.4.1) then if in the same context: +If in any context an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid (§24.4.1) then if in the same context: - `T` provides accessible members qualifying it as both *countable* and *sliceable* (§24.1) From b32d2f2937c5c9e9e6760bfc315a4f0d830b27a4 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Mon, 1 Sep 2025 13:59:07 +0100 Subject: [PATCH 5/8] Update standard/expressions.md Co-authored-by: Rex Jaeschke --- standard/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/expressions.md b/standard/expressions.md index 6a62a93e5..859db629c 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -2264,7 +2264,7 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p - The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` (§24.3). - A new array is created from a shallow copy of the *N* elements of `P` starting at index *S*, if *N* is zero the new array has zero elements. This array becomes the result of the array access. -> > > *Note:* Both *S* and *N* may be zero ($24.3). Indexing an empty array is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty array. The defintion also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty array returned. *end note* +> > > *Note:* Both *S* and *N* may be zero (§24.3). Indexing an empty array is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty array. The definition also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty array returned. *end note* From a43f26445fedd07d9955b3513fe213faafde25fb Mon Sep 17 00:00:00 2001 From: Nigel-Ecma Date: Fri, 5 Sep 2025 17:19:58 +1200 Subject: [PATCH 6/8] - Edits from 240803 meeting - Edit to remove use of use of "new" wrt the result of slicing --- standard/arrays.md | 2 +- standard/expressions.md | 16 ++++++++-------- standard/ranges.md | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/standard/arrays.md b/standard/arrays.md index 1fda69889..a3d60ea23 100644 --- a/standard/arrays.md +++ b/standard/arrays.md @@ -114,7 +114,7 @@ Elements of arrays created by *array_creation_expression*s are always initialize Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference (§9.5) to the array element selected by the indices. -Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to it, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to it, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range`, maintaining the element order. +Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to that type, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to that type, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range`, maintaining the element order. The elements of an array can be enumerated using a `foreach` statement ([§13.9.5](statements.md#1395-the-foreach-statement)). diff --git a/standard/expressions.md b/standard/expressions.md index 859db629c..337c0f565 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -1822,7 +1822,7 @@ null_forgiving_operator ; ``` -*Note*: The postfix null-forgiving and prefix logical negation operators ([§12.9.4](expressions.md#1294-logical-negation-operator)), while represented by the same lexical token (`!`), are distinct. Only the latter may be overridden ([§15.10](classes.md#1510-operators)), the definition of the null-forgiving operator is fixed. *end note* +*Note*: The postfix null-forgiving and prefix logical negation operators ([§12.9.4](expressions.md#1294-logical-negation-operator)), while represented by the same lexical token (`!`), are distinct. Only the latter may be overloaded ([§15.10](classes.md#1510-operators)), the definition of the null-forgiving operator is fixed. *end note* It is a compile-time error to apply the null-forgiving operator more than once to the same expression, intervening parentheses notwithstanding. @@ -2236,7 +2236,7 @@ In this case the compile-time type of the *element_access* depends on the compil If the *primary_expression* of an *element_access* is: -- a value of *array_type*, the *element_access* is an array access ([§12.8.12.2](expressions.md#128122-array-access)); +- a value of an array type, the *element_access* is an array access ([§12.8.12.2](expressions.md#128122-array-access)); - a value of `string` type, the *element_access* is a string access (§string-access); - otherwise, the *primary_expression* shall be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the *element_access* is an indexer access ([§12.8.12.3](expressions.md#128123-indexer-access)). @@ -2260,11 +2260,11 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p - The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. - If the preceding steps have produced a single index value of type `Range` then: - Let *L* be the length of the array referenced by `P`. - - `A` is checked to be valid with respect to *L* (§24.3), if it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. + - `A` is checked to be valid with respect to *L* (§24.3). If it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. - The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` (§24.3). - - A new array is created from a shallow copy of the *N* elements of `P` starting at index *S*, if *N* is zero the new array has zero elements. This array becomes the result of the array access. + - The result of the array access is an array containing a shallow copy of the *N* elements of `P` starting at index *S*. If *N* is zero the array has zero elements. -> > > *Note:* Both *S* and *N* may be zero (§24.3). Indexing an empty array is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty array. The definition also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty array returned. *end note* +> > > *Note:* Both *S* and *N* may be zero ($24.3). Indexing an empty array is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty array. The definition also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty array returned. *end note* @@ -2294,7 +2294,7 @@ The run-time processing of a string access of the form `P[A]`, where `P` is a *p - Let *L* be the length of the string referenced by `P`. - `A` is checked to be valid with respect to *L* (§24.3), if it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. - The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` (§24.3). - - The result of the string access is a new string formed by copying the *N* characters of `P` starting from *S*, if *N* is zero the new string is empty. + - The result of the string access is a string formed by copying the *N* characters of `P` starting from *S*, if *N* is zero the string is empty. > > > *Note:* Both *S* and *N* may be zero (§24.3). Indexing an empty string is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty string. The defintion also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty string returned. *end note* @@ -2305,7 +2305,7 @@ The run-time processing of a string access of the form `P[A]`, where `P` is a *p #### 12.8.12.3 Indexer access -For an indexer access, the *primary_expression* of the *element_access* shall be a variable or value of a class, struct, or interface type, and this type shall implement one or more indexers that are applicable with respect to the *argument_list* of the *element_access*. The *argument_list* shall not cannot contain `out` or `ref` arguments. +For an indexer access, the *primary_expression* of the *element_access* shall be a variable or value of a class, struct, or interface type, and this type shall implement one or more indexers that are applicable with respect to the *argument_list* of the *element_access*. The *argument_list* shall not contain `out` or `ref` arguments. The binding-time processing of an indexer access of the form `P[A]`, where `P` is a *primary_expression* of a class, struct, or interface type `T`, and `A` is an *argument_list*, consists of the following steps: @@ -2317,7 +2317,7 @@ The binding-time processing of an indexer access of the form `P[A]`, where `P` i - If the resulting set of candidate indexers is empty, then no applicable indexers exist, and a binding-time error occurs. - The best indexer of the set of candidate indexers is identified using the overload resolution rules of [§12.6.4](expressions.md#1264-overload-resolution). If a single best indexer cannot be identified, the indexer access is ambiguous, and a binding-time error occurs. - The accessors of the best indexer are checked: - - If the indexer access is the target of an assignment then the indexer shall have a set or ref get accessor, if not a binding-time error occurs; + - If the indexer access is the target of an assignment then the indexer shall have a set or ref get accessor, otherwise, a binding-time error occurs; - Otherwise the indexer shall have a get or ref get accessor, otherwise a binding-time error occurs. The runtime processing of the indexer access consists of the following steps: diff --git a/standard/ranges.md b/standard/ranges.md index 538852b9f..c9ce08b24 100644 --- a/standard/ranges.md +++ b/standard/ranges.md @@ -1,4 +1,4 @@ -# 24 Extended Indexing and Slicing +# 24 Extended indexing and slicing > **Review Note:** This new clause, currently (§24), is placed here temporarily to avoid text changes due to renumbering occurring in chapters & clauses otherwise unaffected by the PR. Its final placement is not yet determined, however between the Arrays ([§17](arrays.md#17-arrays)) and Interfaces ([§18](interfaces.md#18-interfaces)) chapters might be suitable – other placements can be suggested during review. It can be relocated later with just a simple edit to `clauses.json`. @@ -16,7 +16,7 @@ Under the model a type is classified as: - an *extended indexable* collection if it supports an *element_access* expression which has a single argument expression of type `Index` which returns and/or sets a single element of the type, either by value or by reference; and - an *extended sliceable* collection if it supports an *element_access* expression which has a single argument expression of type `Range` which returns a *slice* of the elements of the type by value. -> *Note*: The model does not require that a slice, unlike an element, of the type can be set, but a type may support it as an extension of the model. *end note* +> *Note*: The model does not require that a slice of the type can be set, but a type may support it as an extension of the model. *end note* The model is supported for single-dimensional arrays (§12.8.12.2) and strings (§string-access). @@ -27,7 +27,7 @@ Implicit support for the model is provided for types which do not directly suppo For the purposes of this clause the following terms are defined: - A ***collection*** is a type which represents a group of ***element***s. -- A ***countable collection*** is one which provides a ***countable property*** an `int` valued instance property whose value is the number of elements currently in the group. This property shall be named either `Length` or `Count`, the former is chosen if both exist. +- A ***countable collection*** is one which provides a ***countable property*** an `int`-valued instance property whose value is the number of elements currently in the group. This property shall be named either `Length` or `Count`. The former is chosen if both exist. - A ***sequence*** or ***indexable type*** is a collection: - which is countable; - where every element can be accessed using an *element_access* expression with a single required `int` argument, the ***from-start index***, additional optional arguments are allowed; @@ -35,7 +35,7 @@ For the purposes of this clause the following terms are defined: - an element’s from-start index is the number of elements before it in the sequence, for a sequence containing *N* elements: - the first and last elements have indices of 0 and *N*-1 respectively, and - the ***past-end index***, an index which represents a hypothetical element after the last one, has the value *N*. -- A ***from-end index*** represents an element’s position within a sequence relative to the last element. For a sequence containing *N* elements the first, last and past-end indices are *N*, 1 and 0 respectively. +- A ***from-end index*** represents an element’s position within a sequence relative to the past-end index. For a sequence containing *N* elements the first, last and past-end indices are *N*, 1 and 0 respectively. - A ***range*** is a contiguous run of zero or more indices starting at any index within a sequence. - A ***slice*** is the collection of elements within a range. - A ***sliceable collection*** is one which: @@ -82,7 +82,7 @@ The required members for a type to qualify as a sequence or sliceable may be inh > > - A type can be sliceable without being indexable due to the lack of an (accessible) indexer. > - For a type to be sliceable and/or indexable requires the type to be countable. -> - While the elements of a sequence are ordered by *position* within the sequence the elements themselves need not be ordered by their value, or even orderable. +> - While the elements of a sequence are ordered by *position* within the sequence, the elements themselves need not be ordered by their value, or even orderable. > > *end note* From 24a401709fcfdc1a7722f81f70c6691f903d26d7 Mon Sep 17 00:00:00 2001 From: Nigel-Ecma Date: Fri, 5 Sep 2025 21:29:32 +1200 Subject: [PATCH 7/8] Replace files mangled by github merge --- .../part-O/Reference/sample.tree.red.txt | 2 +- .../part-O/Reference/sample.tree.svg | 3420 ++-- .../Reference/sample.tree.svg | 13110 ++++++++-------- 3 files changed, 8266 insertions(+), 8266 deletions(-) diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.red.txt b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.red.txt index 8f1098836..df00824a7 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.red.txt +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.red.txt @@ -1 +1 @@ -(prog (compilation_unit (namespace_declaration namespace (qualified_identifier (identifier Comments) . (identifier XmlComments) . (identifier UndocumentedKeywords)) (namespace_body { (namespace_member_declaration (class_declaration class (identifier (contextual_keyword yield)) (class_body { (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier Params)) ( (parameter_list (fixed_parameters (fixed_parameter (parameter_modifier (parameter_mode_modifier ref)) (type (contextual_keyword dynamic)) (identifier a)) , (fixed_parameter (parameter_modifier (parameter_mode_modifier out)) (type (contextual_keyword dynamic)) (identifier b))) , (parameter_array params (array_type (non_array_type (contextual_keyword dynamic)) (rank_specifier [ ])) (identifier c))) )) (method_body (block { })))) (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier Params)) ( (parameter_list (fixed_parameters (fixed_parameter (parameter_modifier (parameter_mode_modifier out)) (type (contextual_keyword dynamic)) (identifier a) (default_argument = (expression (literal 2)))) , (fixed_parameter (parameter_modifier (parameter_mode_modifier ref)) (type (contextual_keyword dynamic)) (identifier c) (default_argument = (expression (explicitly_typed_default default ( (type (contextual_keyword dynamic)) )))))) , (parameter_array params (array_type (non_array_type (contextual_keyword dynamic)) (rank_specifier [ ]) (rank_specifier [ ])) (identifier c))) )) (method_body (block { })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) (method_modifier (ref_method_modifier override))) (return_type (class_type string)) (method_header (member_name (identifier ToString)) ( )) (method_body (block { (statement_list (return_statement return (expression (invocation_expression (primary_expression (base_access base . (identifier ToString))) ( ))) ;)) })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) partial) (return_type void) (method_header (member_name (identifier OnError)) ( )) (method_body ;))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) partial) (return_type void) (method_header (member_name (identifier method)) ( )) (method_body (block { (statement_list (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (array_type (non_array_type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) (rank_specifier [ ]))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier a) = (local_variable_initializer (array_creation_expression new (non_array_type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) [ (expression_list (literal 5)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (array_type (non_array_type (integral_type int)) (rank_specifier [ ]))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier (contextual_keyword var)) = (local_variable_initializer (array_initializer { (variable_initializer_list (variable_initializer (literal 1)) , (variable_initializer (literal 2)) , (variable_initializer (literal 3)) , (variable_initializer (literal 4)) , (variable_initializer (literal 5))) })))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier i) = (local_variable_initializer (element_access (primary_expression (identifier a)) [ (argument_list (identifier i)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (namespace_or_type_name (identifier Foo) (type_argument_list < (type_argument (identifier T)) >))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier f) = (local_variable_initializer (object_creation_expression new (type (namespace_or_type_name (identifier Foo) (type_argument_list < (type_argument (integral_type int)) >))) ( ))))))) ;)) (statement (expression_statement (statement_expression (invocation_expression (primary_expression (member_access (primary_expression (identifier f)) . (identifier method))) ( ))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier i)) (assignment_operator =) (expression (inclusive_or_expression (inclusive_or_expression (and_expression (and_expression (additive_expression (additive_expression (additive_expression (identifier i)) + (multiplicative_expression (identifier i))) - (multiplicative_expression (multiplicative_expression (multiplicative_expression (multiplicative_expression (identifier i)) * (unary_expression (identifier i))) / (unary_expression (identifier i))) % (unary_expression (identifier i))))) & (equality_expression (identifier i)))) | (exclusive_or_expression (exclusive_or_expression (identifier i)) ^ (and_expression (identifier i))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (simple_type bool)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier b) = (local_variable_initializer (inclusive_or_expression (inclusive_or_expression (and_expression (and_expression (boolean_literal true)) & (equality_expression (boolean_literal false)))) | (exclusive_or_expression (exclusive_or_expression (boolean_literal true)) ^ (and_expression (boolean_literal false))))))))) ;))) })))) }))) })))) \ No newline at end of file +(prog (compilation_unit (namespace_declaration namespace (qualified_identifier (identifier Comments) . (identifier XmlComments) . (identifier UndocumentedKeywords)) (namespace_body { (namespace_member_declaration (class_declaration class (identifier (contextual_keyword yield)) (class_body { (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier Params)) ( (parameter_list (fixed_parameters (fixed_parameter (parameter_modifier (parameter_mode_modifier ref)) (type (contextual_keyword dynamic)) (identifier a)) , (fixed_parameter (parameter_modifier (parameter_mode_modifier out)) (type (contextual_keyword dynamic)) (identifier b))) , (parameter_array params (array_type (non_array_type (contextual_keyword dynamic)) (rank_specifier [ ])) (identifier c))) )) (method_body (block { })))) (class_member_declaration (method_declaration method_modifiers (return_type void) (method_header (member_name (identifier Params)) ( (parameter_list (fixed_parameters (fixed_parameter (parameter_modifier (parameter_mode_modifier out)) (type (contextual_keyword dynamic)) (identifier a) (default_argument = (expression (literal 2)))) , (fixed_parameter (parameter_modifier (parameter_mode_modifier ref)) (type (contextual_keyword dynamic)) (identifier c) (default_argument = (expression (explicitly_typed_default default ( (type (contextual_keyword dynamic)) )))))) , (parameter_array params (array_type (non_array_type (contextual_keyword dynamic)) (rank_specifier [ ]) (rank_specifier [ ])) (identifier c))) )) (method_body (block { })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) (method_modifier (ref_method_modifier override))) (return_type (class_type string)) (method_header (member_name (identifier ToString)) ( )) (method_body (block { (statement_list (return_statement return (expression (invocation_expression (primary_expression (base_access base . (identifier ToString))) ( ))) ;)) })))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) partial) (return_type void) (method_header (member_name (identifier OnError)) ( )) (method_body ;))) (class_member_declaration (method_declaration (method_modifiers (method_modifier (ref_method_modifier public)) partial) (return_type void) (method_header (member_name (identifier method)) ( )) (method_body (block { (statement_list (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (array_type (non_array_type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) (rank_specifier [ ]))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier a) = (local_variable_initializer (array_creation_expression new (non_array_type (nullable_value_type (non_nullable_value_type (integral_type int)) (nullable_type_annotation ?))) [ (expression_list (literal 5)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (array_type (non_array_type (integral_type int)) (rank_specifier [ ]))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier (contextual_keyword var)) = (local_variable_initializer (array_initializer { (variable_initializer_list (variable_initializer (literal 1)) , (variable_initializer (literal 2)) , (variable_initializer (literal 3)) , (variable_initializer (literal 4)) , (variable_initializer (literal 5))) })))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (integral_type int)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier i) = (local_variable_initializer (element_access (primary_expression (identifier a)) [ (argument_list (identifier i)) ])))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (namespace_or_type_name (identifier Foo) (type_argument_list < (type_argument (identifier T)) >))) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier f) = (local_variable_initializer (object_creation_expression new (type (namespace_or_type_name (identifier Foo) (type_argument_list < (type_argument (integral_type int)) >))) ( ))))))) ;)) (statement (expression_statement (statement_expression (invocation_expression (primary_expression (member_access (primary_expression (identifier f)) . (identifier method))) ( ))) ;)) (statement (expression_statement (statement_expression (assignment (unary_expression (identifier i)) (assignment_operator =) (expression (inclusive_or_expression (inclusive_or_expression (and_expression (and_expression (additive_expression (additive_expression (additive_expression (identifier i)) + (multiplicative_expression (identifier i))) - (multiplicative_expression (multiplicative_expression (multiplicative_expression (multiplicative_expression (identifier i)) * (range_expression (identifier i))) / (range_expression (identifier i))) % (range_expression (identifier i))))) & (equality_expression (identifier i)))) | (exclusive_or_expression (exclusive_or_expression (identifier i)) ^ (and_expression (identifier i))))))) ;)) (statement (declaration_statement (local_variable_declaration (explicitly_typed_local_variable_declaration (type (simple_type bool)) (explicitly_typed_local_variable_declarators (explicitly_typed_local_variable_declarator (identifier b) = (local_variable_initializer (inclusive_or_expression (inclusive_or_expression (and_expression (and_expression (boolean_literal true)) & (equality_expression (boolean_literal false)))) | (exclusive_or_expression (exclusive_or_expression (boolean_literal true)) ^ (and_expression (boolean_literal false))))))))) ;))) })))) }))) })))) diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.svg b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.svg index 6622e7a6e..8d480c6b2 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.svg +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v6/AllInOneNoPreprocessor-v6-split/part-O/Reference/sample.tree.svg @@ -1,26 +1,26 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + @@ -68,18 +68,18 @@ - - - - + + + + - - + + - - - + + + @@ -114,2157 +114,2157 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -type_argument - - - -class_member_declaration - - - -) - - - -identifier - - - -UndocumentedKeywords - - - -array_initializer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ - - -inclusive_or_expression + + +out - - + + ( - - -type - - - + + parameter_modifier - - -array_type - - - -type_argument + + +[ - - -] + + +and_expression - - -class_type + + +exclusive_or_expression - - -multiplicative_expression + + +{ - - + + identifier - - -method_body - - - -= - - - -; - - - -integral_type - - - -b - - - -new + + +statement - - + + ( - - -parameter_list + + +explicitly_typed_local_variable_declarators - - -multiplicative_expression + + +] + + + +i type - - -type + + +] - - -method + + +type_argument_list - - + + identifier - - -a - - - -dynamic + + +[ - - -yield + + +% - - -2 + + +] - - -explicitly_typed_local_variable_declaration + + +explicitly_typed_local_variable_declarator - - -expression_list + + +} - - -dynamic + + +parameter_mode_modifier - - + + identifier - - -non_array_type + + +. - - -expression + + +element_access - - -default_argument + + +type_argument_list - - -method_modifier + + +primary_expression - - -dynamic + + +, - - -explictly_typed_default + + +{ - - -class + + +params - - -default_argument + + +local_variable_initializer - - -, + + +member_name - - -identifier + + +type - - -i + + +; - - -expression + + +identifier - - -prog + + +identifier - - -) + + +{ - - -contextual_keyword + + +fixed_parameters - - -variable_initializer + + +( - - -parameter_array + + +] - - -contextual_keyword + + +local_variable_declaration - - + + identifier - - -} - - - -, + + +identifier - - -b + + +parameter_mode_modifier - - -var + + +inclusive_or_expression - - -= + + +member_name - - -unary_expression + + +Params - - -identifier + + +explicitly_typed_local_variable_declaration - - -namespace_or_type_name + + +ref - - -i + + +} - - -expression + + +multiplicative_expression - - -identifier + + +explicitly_typed_local_variable_declaration - - -primary_expression + + +b - - -{ + + +new - - -primary_expression + + +UndocumentedKeywords - - -int + + += - - -dynamic + + +out - - -non_array_type + + +> - - -declaration_statement + + +integral_type - - -primary_expression + + +statement - - -return + + +| - - -argument_list + + +assignment_operator - - -identifier + + +class_member_declaration - - -identifier + + +type - - -XmlComments + + +type_argument - - -out + + +c - - -local_variable_initializer + + +f - - -ref + + +method_declaration - - -i + + +contextual_keyword - - -member_name + + +] - - -method_modifiers + + +identifier - - -parameter_mode_modifier + + +literal - - -type + + +class_member_declaration - - -method_modifiers + + +literal - - -dynamic + + +; - - -fixed_parameter + + +ToString - - -Foo + + +] - - + + identifier - - -{ + + +return_statement + + + +non_array_type - - -explicitly_typed_local_variable_declaration + + +, - - -c + + +parameter_modifier - - -contextual_keyword + + +return_type - - -namespace_declaration + + +block - - -compilation_unit + + +identifier - - -{ + + +( - - -= + + +statement_expression - - -block + + +simple_type - - + + class_member_declaration - - -inclusive_or_expression - - - -{ + + +int - - -statement + + +equality_expression - - -true + + +and_expression - - -public + + +method_body - - -; + + ++ - - -local_variable_initializer + + +method_modifier - - -dynamic + + +explicitly_typed_default - - -[ + + +and_expression - - -literal + + +, - - -parameter_list + + += - - -integral_type + + +range_expression - - -f + + +false - - -additive_expression + + +ref_method_modifier - - -namespace_member_declaration + + +class_member_declaration - - -new + + +variable_initializer_list - - -literal + + +XmlComments - - -+ + + +exclusive_or_expression - - + + a - - -parameter_modifier + + +] - - -= + + +contextual_keyword - - -, + + +method_declaration - - + + identifier - - -bool - - - -statement_list + + +( - - -{ + + +method_modifiers - - -local_variable_initializer + + +[ - - -parameter_modifier + + +) - - -1 + + +& - - -expression + + +. - - -rank_specifier + + +non_nullable_value_type - - -additive_expression + + +parameter_list - - -. + + +4 - - + + identifier - - -declaration_statement + + +type - - + + int - - -boolean_literal + + +explicitly_typed_local_variable_declaration - - -Foo + + +, - - -{ + + +? - - -) + + +explicitly_typed_local_variable_declarators - - -params + + +literal - - -statement + + +local_variable_initializer - - -partial + + +identifier - - + + i - - -5 + + +T - - -method_modifiers + + +a - - -fixed_parameters + + +true - - -namespace + + +local_variable_declaration - - -array_type + + +} - - -boolean_literal + + +explicitly_typed_local_variable_declarator - - -explicitly_typed_local_variable_declaration + + +Params - - -and_expression + + +variable_initializer - - -and_expression + + +( - - -contextual_keyword + + +i - - -method_modifiers + + +; - - -statement + + +class_type - - -integral_type + + +local_variable_declaration - - -identifier + + +dynamic - - -ref_method_modifier + + +local_variable_initializer - - -identifier + + +a + + + +i + + + +declaration_statement + + + +additive_expression - - + + identifier - - -method_body + + +) + + + +literal + + + +public + + + +base_access + + + +namespace_or_type_name - - -and_expression + + +; - - -explicitly_typed_local_variable_declaration + + +contextual_keyword - - -local_variable_initializer + + +additive_expression - - -local_variable_declaration + + +type - - -a + + +method_header - - -explicitly_typed_local_variable_declarators + + +explicitly_typed_local_variable_declarator - - -] + + +) - - -identifier + + +assignment - - -> + + +OnError - - -int + + +method_header - - -( + + +statement - - -nullable_value_type + + +literal - - + + member_name - - -& + + +partial - - -Comments + + +explicitly_typed_local_variable_declarator - - -integral_type + + +prog - - -} + + +and_expression - - -] + + +variable_initializer - - -and_expression + + +identifier - - -rank_specifier + + +boolean_literal - - -* + + +method_modifiers - - -range_expression + + +multiplicative_expression - - -namespace_body + + +^ - - -void + + +type - - -identifier + + +f - - + + +( + + + method_header - - -{ + + +parameter_mode_modifier - - + + +compilation_unit + + + [ - - + + type - - -identifier - - - -range_expression - - - -; + + +variable_initializer - - -i + + +boolean_literal - - -method_header + + +( - - -int + + +< - - + + expression_statement - - -identifier + + +explicitly_typed_local_variable_declarators - - -ref_method_modifier + + +local_variable_declaration - - -i + + +dynamic - - -statement_expression + + +> - - -. + + +identifier - - -method_modifier + + +; - - -base_access + + +[ - - -; + + +fixed_parameter - - -statement + + +, - - -method + + +integral_type - - -element_access + + +contextual_keyword - - -block + + +method_body - - -default + + +contextual_keyword - - -non_nullable_value_type + + +2 - - -3 + + +expression - - -a + + +{ - - -, + + +identifier - - -array_creation_expression + + +void - - -non_array_type + + +public - - -4 + + +expression_list - - + + +rank_specifier + + + contextual_keyword - - -partial + + +) + + + +void - - + + explicitly_typed_local_variable_declarator - - -identifier + + +string - - -) + + +rank_specifier - - -method_modifiers + + +statement - - -literal + + +type - - + + identifier - - -type_argument_list - - - -declaration_statement + + +identifier - - -member_name + + +identifier - - -literal + + +bool - - -rank_specifier + + +identifier - - -i + + +array_type - - -non_nullable_value_type + + +identifier - - -? + + +statement_expression - - -type + + +ref_method_modifier - - -multiplicative_expression + + +ref_method_modifier - - -method_declaration + + +identifier - - -ref + + +) - - -override + + +dynamic - - -invocation_expression + + +) - - -literal + + +method_declaration - - -} + + +, - - -} + + += - - -method_declaration + + +nullable_type_annotation - - -parameter_modifier + + +ref_method_modifier - - -> + + +ToString - - -[ + + +method_body - - -} + + +i - - -method_declaration + + += - - -[ + + +non_array_type - + = - - -type + + +void - - -c + + +identifier - - -; + + +multiplicative_expression - - -| + + +class_declaration - - -contextual_keyword + + +member_name - - -exclusive_or_expression + + +/ - - -fixed_parameters + + +i - - -variable_initializer + + +identifier - - -local_variable_declaration + + +* - - -int + + +qualified_identifier - - -% + + +statement - - -identifier + + +Foo - - -) + + +non_array_type - - -2 + + +invocation_expression - - -parameter_mode_modifier + + +method_declaration - - -[ + + += - - -] + + +non_array_type - - -( + + +return_type - - -false + + +expression - - -identifier + + +c - - -return_statement + + +^ - - -invocation_expression + + +type_argument - - -class_body + + +class_member_declaration - - -nullable_type_annotation + + +Foo - - -public + + +Comments - - -method_body + + +method_modifier - - -f + + +true - - -contextual_keyword + + +expression - - + + block - - -method_body - - - -assignment + + +integral_type - - -simple_type + + +identifier - - -statement_expression + + +a - - -non_array_type + + +default_argument - - -void + + +range_expression - - -type + + +range_expression - - -& + + +multiplicative_expression - - -ref_method_modifier + + +void - - + + identifier - - -identifier + + += - - -T + + +dynamic - - -parameter_mode_modifier + + +; - - -( + + +params - - -; + + +declaration_statement - - -namespace_or_type_name + + +method_header - - -method_modifier + + +expression_statement - - -fixed_parameter + + +argument_list - - -void + + +primary_expression - - -and_expression + + +namespace - - -Params + + +return_type - - -non_array_type + + +equality_expression - - -local_variable_declaration + + +contextual_keyword - - -method_header + + +default_argument - - -out + + +non_nullable_value_type - - -} + + +fixed_parameter - - -explicitly_typed_local_variable_declarators + + +identifier - - -i + + +default - - -identifier + + +int - - -block + + +object_creation_expression - - -/ + + +5 - - -Params + + +( - - + + identifier - - -class_member_declaration + + +{ - - + + = - - + + +type + + + i - - -( + + +new - - -) + + +b - - + + statement_list - - -statement - - - -ToString - - - -qualified_identifier - - - -explicitly_typed_local_variable_declarator - - - -additive_expression + + +public - - -local_variable_declaration + + +1 - - -parameter_array + + +rank_specifier - - + + method_body - - + + identifier - - -exclusive_or_expression - - - -rank_specifier - - - -statement - - - -variable_initializer_list + + +namespace_member_declaration - - -. + + +dynamic - - -local_variable_initializer + + +base - - -< + + +statement_list - - -parameter_mode_modifier + + +var - - -) + + +i - - -nullable_type_annotation + + +identifier - - -; + + +} return_type - - -i + + +nullable_value_type - - -multiplicative_expression + + +integral_type - - -identifier + + +inclusive_or_expression - - -expression_statement + + +primary_expression - - -identifier + + +fixed_parameters - - -method_declaration + + +block - - -variable_initializer + + +partial - - -variable_initializer + + +int - - -, + + +member_access - - -void + + +method - - -identifier + + +i - - -type + + +primary_expression - - -range_expression + + +i - - -array_type + + +fixed_parameter - - + + +array_creation_expression + + + +nullable_value_type + + + +invocation_expression + + + literal - - -class_member_declaration + + +int - - -statement + + +. - - -boolean_literal + + +ref - - -return_type + + +declaration_statement - - -return_type + + +contextual_keyword - - -; + + +, - - -method_declaration + + +i - - -explicitly_typed_local_variable_declarator + + +dynamic - - -( + + +inclusive_or_expression - - -] + + +and_expression - - -member_name + + +boolean_literal - - -variable_initializer + + +method_header - - -explicitly_typed_local_variable_declarator + + +. - - -| + + +override - - -member_access + + +local_variable_declaration - - -explicitly_typed_local_variable_declarators + + +method_modifiers - - -identifier + + +2 - - -nullable_value_type + + +identifier - - -equality_expression + + +5 - - -fixed_parameter + + +} - - -string + + +inclusive_or_expression - - + + type - - -explicitly_typed_local_variable_declarators + + +array_type - - -^ + + +method_modifiers - - + + identifier - - -class_declaration + + +parameter_modifier + + + +[ + + + +{ + + + +block + + + +; + + + +exclusive_or_expression - - -= + + +c - - -, + + +literal - - -dynamic + + +identifier - - -OnError + + +unary_expression - - -integral_type + + +dynamic - - -inclusive_or_expression + + +class_body - - -( + + +method_body - - -and_expression + + +i - - -false + + +} - - -exclusive_or_expression + + +& - - -identifier + + +and_expression - - -rank_specifier + + +boolean_literal - - -explicitly_typed_local_variable_declaration + + +fixed_parameter - - -assignment_operator + + +integral_type - - -exclusive_or_expression + + +namespace_or_type_name - - -; + + +additive_expression - - -contextual_keyword + + +namespace_body - - -array_type + + +? - - -) + + +namespace_declaration contextual_keyword - - -5 - - - -equality_expression + + +member_name - - -ToString + + +identifier - - -return_type + + +class - - -) + + +method - - -method_header + + +identifier - - -c + + +) - - -[ + + +rank_specifier - - -explicitly_typed_local_variable_declarators + + +; - - -explicitly_typed_default + + +parameter_modifier - - -ref_method_modifier + + +) - - -identifier + + +parameter_mode_modifier - - -class_member_declaration + + +return_type - - -, + + +array_initializer - - + + declaration_statement - - + + +identifier + + + method_modifier - - -local_variable_declaration + + +) - - -type + + +yield - - -} + + +nullable_type_annotation - - -inclusive_or_expression + + +method_modifiers - - -literal + + +; - - -base + + +non_array_type - - -i + + +false - - -params + + +exclusive_or_expression - - -. + + +explicitly_typed_local_variable_declarators - - -[ + + +parameter_array - - -, + + +3 - - -] + + +, - - -= + + +parameter_list - - -primary_expression + + +rank_specifier - - -^ + + +local_variable_initializer - - -member_name + + +array_type - - -< + + +variable_initializer - - -explicitly_typed_local_variable_declarator + + +{ - - -identifier + + +expression - - -fixed_parameter + + +array_type - - -method_header + + +statement - - -declaration_statement + + +- - - -i + + +explicitly_typed_local_variable_declaration - - -- + + +parameter_array - - -return_type + + +} - - -? + + +explicitly_typed_local_variable_declaration - - -object_creation_expression + + +< - - -] + + +declaration_statement - - -type_argument_list + + +return - - -multiplicative_expression + + +method_modifier - - -boolean_literal + + +method_declaration - - -( + + +variable_initializer - - -true + + +explicitly_typed_local_variable_declarators - - + + identifier - + + +local_variable_initializer + + + +statement + + + +multiplicative_expression + + + +type + + + +| + + \ No newline at end of file diff --git a/tools/GrammarTesting/Tests/Parsing/Samples/v7/AllInOneNoPreprocessor-v7/Reference/sample.tree.svg b/tools/GrammarTesting/Tests/Parsing/Samples/v7/AllInOneNoPreprocessor-v7/Reference/sample.tree.svg index a09be1b35..0069b49cd 100644 --- a/tools/GrammarTesting/Tests/Parsing/Samples/v7/AllInOneNoPreprocessor-v7/Reference/sample.tree.svg +++ b/tools/GrammarTesting/Tests/Parsing/Samples/v7/AllInOneNoPreprocessor-v7/Reference/sample.tree.svg @@ -2207,8844 +2207,8844 @@ - - -} + + +class_type - - -= + + +argument_name - - + + +method_header + + + identifier - - -type + + +( - - -method_body + + +implicitly_typed_local_variable_declaration - - + + identifier - - -relational_expression + + +type_argument_list - - -statement + + ++ - - -x + + +statement_list - - -statement + + +additive_expression - - -> + + +Vector3 - - -, + + +ptr - - -parameter_modifier + + +implicitly_typed_local_variable_declarator - - -) + + +declaration_statement - - -{ + + +statement statement_list - - -literal + + +unmanaged_type + + + +method_header + + + +; ) - - -type - - - -invocation_expression + + +identifier - - -primary_expression + + +s - - -Test + + +1 - - -expression_statement + + +( - - -member_name + + +10 - - -class_type + + +( - - -null_literal + + +argument_value - - -value + + +foo - - -stackalloc_initializer_element_list + + +identifier - - -expression + + +explicitly_typed_local_variable_declaration - - -) + + += - - -explicitly_typed_local_variable_declarator + + +identifier - - -parameter_modifier + + +declaration_statement - - -throw_expression + + +equality_expression - - -unmanaged_type + + +identifier - - -int + + +( - - -1 + + +identifier - - -explicitly_typed_local_variable_declaration + + +statement_expression - - -identifier + + +variable_reference - - -argument + + +argument_list - - + + statement - - -1 + + +argument_list - - -simple_designation + + +( - - -statement + + +method_body - - -local_variable_initializer + + +identifier - - -statement + + +expression - - -is + + +local_variable_declaration - - -constant_expression + + +identifier - - -( + + +, - - -< + + +; - - + + type - - -tuple_expression - - - -Vector3 - - - -; + + +tuple_element - - -int + + +boolean_expression - - -statement + + +identifier - - -v2 + + += - - -ref_method_modifier + + +explicitly_typed_local_variable_declarators - - -identifier + + +struct_member_declaration - - -{ + + +: - - -int + + +explicitly_typed_local_variable_declarator - - -stackalloc_initializer + + +arr - - -identifier + + +fixed_parameter - - -} + + +method_modifiers - - -, + + +type - - -ref + + +await - - -identifier + + +] - - + + variable_reference - - + + +unmanaged_type + + + identifier - - -local_variable_type + + +type - - -explicitly_typed_local_variable_declaration + + +( - - -; + + +identifier - - -implicitly_typed_local_variable_declarator + + +int - - -. + + +primary_expression - - -int + + +statement - - -member_access + + +assignment_operator - - + + identifier - - -method_modifiers + + +identifier - - -local_variable_initializer + + +args - - -default + + +DoSomething - - -struct_member_declaration + + +primary_expression - - -tuple_element + + +c - - -pattern + + +) - - -ref + + +} - - -X + + +; - - -explicitly_typed_local_variable_declarators + + +assignment - - -b + + +< - - -implicitly_typed_local_variable_declaration + + +type_argument - - -default + + +; - - -ref - - - -CSharp70 + + +identifier - - -type_argument + + +primary_expression - - -statement + + +, - - -local_variable_initializer + + +identifier - - -integral_type + + +{ - - -null_coalescing_expression + + +( - - -X + + +primary_expression - - -identifier + + +; - - -primary_expression + + +) - - -identifier + + +M1_Trace - - -public + + +explicitly_typed_local_variable_declarators - - -=> + + +member_access - - -class_member_declaration + + +additive_expression - - + + primary_expression - - -pattern + + +explicit_anonymous_function_parameter - - -< + + +class_member_declaration - - -case + + +5 - - -statement_list + + +) - - -ref_method_modifier + + +assignment - - -type + + +ref_kind - - -method_body + + +if - - -void + + +anonymous_function_signature - - -identifier + + +} - - -( + + +age - - -invocation_expression + + +stackalloc_expression - - + + +member_access + + + fixed_parameter - - -method_header + + +Guid - - -, + + +declaration_statement - - -additive_expression + + +method_body - - -ref_kind + + +throw_expression - - -readonly + + +member_name - - -identifier + + +] - - -literal + + +s - - -arr + + +type - - -, + + +new - - + + identifier - - -public + + +StackallocArrayInitializer - - -argument_value + + +[ - - -member_access + + +PatternBasedFixed - - -variable_reference + + +statement - - -argument + + +identifier - - -namespace_member_declaration + + +X - - -method_modifier - - - -element_access + + +multiplicative_expression - - -= + + +argument_value - - -primary_expression + + +statement_list - - -identifier + + +operator_modifier - - -identifier + + +} - - -method_declaration + + +explicitly_typed_local_variable_declarator - - -string + + +< - - + + tuple_element - - -statement + + +identifier - - -< + + +Span - - -void + + +return_type - - -{ + + +T - - -statement_list + + +* - - -method_header + + +struct_body - - -int + + +ref - - -anonymous_function_signature + + +G - - -identifier + + +null_coalescing_expression - - -; + + +out - - -member_access + + +expr - - -literal + + +variable_reference - - -} + + +2 - - -in + + +literal - - -arr + + +contextual_keyword - - -argument_list + + +statement_list - - -type_parameter_list + + +public - - -: + + +method_header - - -identifier + + +method_declaration - - -) + + +statement_list - - + + +Hello + + + identifier - - -explicitly_typed_local_variable_declarator + + +argument_list - - -null_conditional_member_access + + +{ - - -} + + +Type - - -parameter_list + + +local_variable_declaration - - + + integral_type - - -local_variable_declaration - - - -, + + +. - - -block + + +) - - -3 + + +> - - -explicitly_typed_local_variable_declarator + + +parameter_mode_modifier - - -parameter_modifier + + +int - - -statement_list + + +stackalloc - - -( + + +identifier - - -v2 + + +) - - -> - - - -{ - - - -void - - - -] - - - -variable_reference + + +type - - -, + + +integral_type - - + + identifier - - -=> - - - -expression_statement + + +relational_expression - - -identifier + + +expression - - + + type - - -primary_expression - - - -integral_type - - - -; - - - -null + + +implicitly_typed_local_variable_declaration - - -method_declaration + + +e - - -declaration_expression + + +statement_list - - -=> + + +variable_reference - - -member_name + + +, - - -struct_body + + +method_header - - + + statement_expression - - -member_access + + +local_variable_type - - -return_statement + + +< - - -primary_expression + + +identifier - - -struct_body + + +z - - + + +expression + + + ) - - -y + + +method_modifiers - - -integral_type + + +v1 - - -member_access + + +block - - -literal + + +0 - - -additive_expression + + +explicitly_typed_local_variable_declarator - - -literal + + +arg - - -, + + +var - - -Hello + + +tuple_expression - - -primary_expression + + +ref class - - -> + + +argument_name - - -return_type + + +statement_list - - -= + + ++ - - -?? + + +> - - -identifier + + +, - - -3 + + +equality_expression - - -pointer_type + + +[ - - -literal + + +namespace_or_type_name - - -int + + +declaration_statement - - -= + + +stackalloc_initializer_element_list - - -f2 + + +local_function_body - - -( - - - -. + + +in - - -personAge + + +declaration_statement - - -) + + +ref_method_modifier - - -explicitly_typed_local_variable_declaration + + +argument_list - - -x + + +method_modifier - - -expression + + +identifier - - -literal + + += - - -class_type + + +local_function_header - - + + identifier - - -} + + +< - - -) + + +type - - -* + + +ref_return_type - - -fixed_parameter + + +primary_expression - - -stackalloc_expression + + += - - -variable_reference + + +explicitly_typed_local_variable_declaration - - -statement + + +: - - -T + + +? - - -identifier + + +block - - -statement_list + + +null - - -expression_statement + + +local_variable_declaration - - -namespace_or_type_name + + +stackalloc_expression - - + + primary_expression - - + + +identifier + + + +[ + + + +parameter_modifier + + + ref - - -: + + +switch_label - - -statement + + +integral_type - - -string + + +relational_expression - - -OutVar + + +identifier - - -result + + +type - - -explicitly_typed_local_variable_declarator + + +identifier - - -variable_reference + + +operator_declaration - - -bool + + +method_modifiers - - -equality_expression + + +( - - + + type_argument - - -member_access + + +} - - -primary_expression + + +; - - -{ + + +element_access - - -declaration_pattern + + +additive_expression - - -explicitly_typed_default + + +identifier - - + + parameter_list - - -identifier + + +block - - -member_name + + +type - - -declaration_statement + + +integral_type - - -) + + +name - - -relational_expression + + +explicitly_typed_local_variable_declarators - - -type + + +( - - -class_body + + +method_modifier - - + + +list + + + +explicitly_typed_local_variable_declaration + + + +unmanaged_type + + + identifier - - -( + + +age - - -variable_reference + + +local_variable_declaration - - -argument_list + + +anonymous_function_body - - -a + + += - - -pattern + + +namespace_or_type_name - - -Choice + + +explicitly_typed_local_variable_declarator - - -primary_expression + + +, - - -identifier + + +local_variable_type - - -DefaultWithoutTypeName + + +fixed_parameter - - -block + + +weird - - -explicitly_typed_local_variable_declaration + + +Vector3 - - -argument_list + + +; - - -int + + +. - - -array_type + + +void - - -( + + +void - - + + +{ + + + ) - - -multiplicative_expression + + +1 - - -variable_reference + + +argument - - -) + + +; - - -tuple_type_element + + +shift_expression - - -type_argument + + +if_statement - - -true + + +method_modifiers - - -identifier + + +argument_list - - -; + + +parameter_mode_modifier - - -identifier + + +statement - - -switch_block + + +ref - - -member_access + + +fixed - - -identifier + + +DoSomething - - -boolean_expression + + +type - - -( + + +variable_declarators - - -argument_list + + +method_header - - -boolean_literal + + +anonymous_function_signature - - -contextual_keyword + + +type_parameter_constraints_clause - - -literal + + +element_access - - + + identifier - - -type + + +identifier - - -void + + +BinaryLiterals - - -; + + +{ - - -( + + +member_name - - -argument + + +parameter_list - - -primary_expression + + +namespace_member_declaration - - -X + + +expression - - -args + + +hex - - -local_variable_declaration + + +class_member_declaration - - -literal + + +x - - -tuple_element + + +explicitly_typed_local_variable_declarator - - + + +!= + + + identifier - - -argument_value + + +literal - - -field_declaration + + +statement_list - - -method_declaration + + +buffer_element_type - - -v1 + + +in - - -additive_expression + + +method_modifiers - - -stackalloc + + +integral_type - - -real + + +void - - -Vector3 + + +) - - -identifier + + +( - - -explicitly_typed_default + + +switch_label - - -identifier + + +block - - -ref_local_variable_declarator + + +declaration_statement - - + + expression - - -member_name + + +personAge - - -fixed_pointer_declarators + + +member_access - - -method_body + + +block - - -identifier + + +primary_expression - - -( + + +method_body - - -< + + +LeadingSeparator - - -method_header + + +stackalloc_element_initializer - - -ref + + +argument_list - - -readonly + + +( - - -s + + +; - - -, + + +null - - -args + + +f2 - - -member_name + + +void - - -statement_expression + + +int - - -fixed_parameter + + +identifier - - -5 + + +statement - - -; + + +type_argument - - -identifier + + +; - - -invocation_expression + + +local_variable_declaration - - -method_declaration + + +expression_statement - - -= + + +identifier - - -method_header + + +explicitly_typed_ref_local_variable_declaration - - -fixed_parameter + + +; - - + + class_member_declaration - - -argument - - - -ref_kind + + +return_type - - -type + + +) - - -2 + + +statement - - -1 + + +method_modifiers - - -member_access + + +, - - -variable_reference + + +switch_label - - -ptr + + +( - - -boolean_expression + + +ref - - -int + + +[ - - -public + + +50 - - -indexer_declarator + + +( - - + + identifier - - -block - - - -binary_operator_declarator + + += - - -statement + + +ref_kind - - -) + + +condition - - -invocation_expression + + +otherArr - - -await + + +primary_expression - - -50 + + +statement_list - - -if_statement + + +} - - -0x1b_a0_44_fe + + +method_modifier - - -parameter_mode_modifier + + +identifier - - -statement_list + + +switch_statement - - -explicitly_typed_local_variable_declarators + + +{ - - -identifier + + +, - - -fixed_parameter + + +class_member_declaration - - -myFixedField + + +1_2_3 - - -expression + + +element_access - - -string + + +3 - - -, + + +variable_reference - - -; + + +value - - -; + + +type_argument_list - - -fixed_parameter + + +method_declaration - - -decorated_type_parameter + + +statement - - -unsafe_modifier + + +expression - - -literal + + +argument - - -local_variable_declaration + + +pattern - - -; + + +identifier - - -class_declaration - - - -fixed - - - -Span - - - -DoSomething - - - -method_modifiers - - - -declaration_statement - - - -literal - - - -literal - - - -, - - - -literal - - - -method_header - - - -0 - - - -null - - - -declaration_statement - - - -, - - - -identifier - - - -void - - - -declaration_statement - - - -) - - - -type - - - -[ - - - -multiplicative_expression - - - -identifier - - - -local_variable_initializer - - - -type - - - -stackalloc_initializer - - - -switch_section - - - -primary_expression - - - -await - - - -T - - - -identifier - - - -operator_declarator - - - -Hello - - - -variable_reference - - - -identifier - - - -integral_type - - - -name - - - -fixed_pointer_initializer - - - -, - - - -tuple_element - - - -Y - - - -relational_expression - - - -class_member_declaration - - - -ref_method_modifier - - - -x - - - -{ - - - -] - - - -class_type - - - -( - - - -t2 - - - -statement_list - - - -method_modifier - - - -variable_declarators - - - -. + + +object_creation_expression method_declaration - - -age - - - -tuple_type_element - - - -: - - - -multiplicative_expression - - - -identifier - - - -ref_method_modifiers - - - -Where - - - -shift_expression - - - -[ - - - -block - - - -personAge - - - -stackalloc_element_initializer - - - -parameter_list - - - -expression - - - -default - - - -statement - - - -argument + + += - - -statement + + +argument_list - - -explicitly_typed_local_variable_declaration + + +? - - + + +break + + + ) - - -default + + +primary_expression - - -struct_modifier + + +member_access - - -parenthesized_expression + + +method_modifier - - -; + + +local_variable_initializer - - -} + + +Hello - - -block + + +. - - -return_type + + +statement_expression - - -identifier + + +r1 - - -identifier + + +class_member_declaration + + + +assignment + + + +type_argument_list fixed_parameters - - -{ + + +integral_type - - -identifier + + +} - - -identifier + + +parameter_modifier - - -class_member_declaration + + +stackalloc_element_initializer - - -identifier + + +return - - -+ + + +type_parameter_list - - + + , - - -Vector3 + + +a - - -fixed + + +v - - -relational_expression + + +member_access - - -block + + +ref - - -method_declaration + + +[ - - -ReadonlyRef1 + + +; - - -statement + + +[ - - -public + + +[ - - -namespace_or_type_name + + +indexer_declarator - - -) + + +local_variable_declaration - - -age + + +T - - -local_variable_initializer + + +int - - + + identifier - - -F + + +v2 - - + + +public + + + +, + + + +integral_type + + + identifier - - -primary_expression + + +NullReferenceException - - -type + + +return_statement - - -A + + +integral_type - - -; + + +2 - - -, + + +member_access - - -explicitly_typed_local_variable_declarators + + +; - - -Vector3 + + +3 - - -] + + +null_coalescing_expression - - -. + + +v1 assignment_operator - - -tuple_type_element + + +) - - -t1 + + +fixed_parameter - - -integral_type + + +member_access - - -= + + +identifier - - -) + + +operator - - + + +return_statement + + + +class_member_declaration + + + +ref_kind + + + +class_member_declaration + + + +local_function_body + + + primary_expression - - -} + + +identifier - - -, + + +DigitSeparators - - -additive_expression + + += - - -fixed_parameter + + +void - - -block + + +ref_method_modifier - - -block + + +expression_statement - - -identifier + + +invocation_expression - - + + identifier - - -expression_statement + + +return_statement - - -literal + + +variable_reference - - -invocation_expression + + +void - - -primary_expression + + +DoSomething - - -if_statement + + +parameter_list - - -; + + +statement - - -statement_list + + +} - - -TupleRecognize + + +null_coalescing_expression - - -statement_expression + + +, - - -method_modifiers + + +Blittable - - -static + + +embedded_statement - - -null_literal + + +struct_modifier - - -method_body + + +type - - -expression_statement + + +"A" - - -, + + +return_statement - - -primary_expression + + += - - -3 + + +; - - -async + + +method_header - - -literal + + +block - - + + ++ + + + +double + + + +CSharp71 + + + +{ + + + > - - + + +simple_designation + + + +identifier + + + +string + + + ) - - -argument + + +{ - - -TValue + + +identifier - - -[ + + +fixed_parameter - - -block + + +type - - -1_2__3___4____5_____6______7_______8________9 + + +i - - -type + + +argument_list - - -namespace_member_declaration + + +statement - - -) + + +stackalloc_initializer_element_list - - -boolean_literal + + +variable_reference - - -literal + + +method_declaration + + + +identifier fixed_parameters - - -implicitly_typed_local_variable_declaration - - - -relational_expression - - - -member_access - - - -E + + +identifier - - -value_type + + +statement - - -name + + +method_declaration - - -; + + +[ - - -class_type + + +return - - + + identifier - - -stackalloc - - - -return_statement + + +return - - -method_body + + +literal - - -struct_body + + +identifier - - -integral_type + + +string - - -unary_expression + + +argument_list - - -operator_modifier + + +element_access - - -additive_expression + + +boolean_literal - - -fixed_size_buffer_modifier + + +identifier - - -ref_return_type + + +identifier - - -additive_expression + + +relational_expression - - -method_modifiers + + += - - -relational_expression + + +method_declaration - - -parameter_mode_modifier + + +await_expression - - -argument_list + + +literal - - -s + + +integral_type - - -3 + + +} - - -literal + + +multiplicative_expression - - -b + + +, - - -type_argument + + +=> - - -; + + +arr - - -0 + + +identifier - - -argument_list + + +} - - -123 + + +lambda_expression - - -explicitly_typed_local_variable_declarators + + +return_type - - -identifier + + += - - -explicitly_typed_local_variable_declarator + + +argument - - -type_parameter_list + + +} - - -tuple_type_element + + +method_declaration - - -embedded_statement + + +nullable_type_annotation - - -member_name + + +{ - - -( + + +T - - -member_name + + +fixed_parameters - - -return_statement + + +{ - - -public + + +bool - - -stackalloc_element_initializer + + +unary_expression - - -class_member_declaration + + +Vector3 - - -!= + + +return_statement - - -statement_list + + +primary_expression - - -field_declaration + + +block - - -string + + +unary_expression - - + + ( - - -( + + +explicitly_typed_local_variable_declarators - - -statement + + +Task - - -( + + +H - - -TryParse + + +invocation_expression - - -BinaryLiterals + + +struct_member_declaration - - -literal + + +class_type - - -statement_list + + +type - - -struct_member_declaration + + +int - - -( + + +void - - -identifier + + +if - - -] + + +local_variable_type - - -declaration_statement + + +else - - -integral_type + + +> - - -} + + +expression_statement - - -non_nullable_value_type + + +expression - - -variable_reference + + +nullableResult - - + + ( - - -primary_expression + + +c - - -) + + +anonymous_function_body - - -var + + +argument_list - - -= + + +t - - -explicitly_typed_local_variable_declarators + + +f1 - - -expression_statement + + +member_access - - -) + + +is + + + +primary_expression + + + +( + + + +namespace_member_declaration - - -identifier + + +type - - -class_member_declaration + + +method_body - - -50 + + +void - - -= + + +compilation_unit - - -argument_value + + +? - - + + +method_declaration + + + identifier - - -statement_expression + + +{ - - -boolean_expression + + +block - - -identifier + + +type_argument - - -Vector3 + + +DefaultWithoutTypeName - - -struct_member_declaration + + +identifier - - + + { - - -readonly + + +. - - -explicitly_typed_local_variable_declarators + + +type - - -Type + + +primary_expression - - -return_type + + +) - - + + +=> + + + +ref_method_body + + + block - - -argument_list + + +class_type - - -field_modifier + + +item - - -block + + +LocalFunctions - - -identifier + + +f2 - - -< + + +namespace_or_type_name - - -identifier + + +. - - -var + + +literal - - -additive_expression + + +unmanaged_type - - -type + + +parameter_mode_modifier - - -} + + +ref - - -identifier + + +literal - - -, + + +pattern - - -block + + +explicitly_typed_default - - -ref_method_modifier + + +block - - -B + + +} - - -floating_point_type + + +return - - -1 + + +v2 - - -integral_type + + +primary_expression - - -statement_expression + + +ref - - -local_variable_initializer + + +block - - -relational_expression + + +expression_statement - - -identifier + + +expression_statement - - -argument_list + + +primary_expression - - -argument + + +args - - -personName + + +expression_statement - - -member_name + + +argument_name - - -type + + +> - - -[ + + +variable_reference - - -namespace_or_type_name + + +public - - -additive_expression + + +local_variable_type - - -identifier + + +r1 - - -primary_expression + + +statement - - -unmanaged + + +explicitly_typed_local_variable_declarators - - -statement_list + + +throw - - -declaration_statement + + +async - - -simple_type + + +argument_value - - -embedded_statement + + +. - - -statement + + +int - - -return + + +local_variable_declaration - - -method_modifier + + +ref - - -block + + +argument - - -statement_expression + + +Y - - -< + + +2 - - -if_statement + + +Where - - -var + + +=> - - -} + + +1_2__3___4____5_____6______7_______8________9 - - -} + + +, - - -ref_local_variable_declarators + + +explicitly_typed_local_variable_declarators - - -invocation_expression + + +s - - -in + + +ref - - -integral_type + + +method_body - - -expression_statement + + +identifier - - -argument + + +method_declaration - - -value2 + + +identifier - - -embedded_statement + + +implicitly_typed_local_variable_declaration - - -member_name + + +declaration_pattern - - -ref + + +method_modifiers - - -fixed_parameter + + +return_type - - -argument_list + + +class_type - - -method_declaration + + +name - - -{ + + +ref_method_modifier - - -identifier + + +variable_reference - - -class_body + + +local_function_declaration - - -( + + +} - - + + +rank_specifier + + + , - - -anonymous_function_signature + + +statement - - -item + + +invocation_expression + + + +explicitly_typed_local_variable_declarator - - -identifier + + +public - - -( + + +primary_expression - - -( + + +fixed_parameter - - -this + + +equality_expression - - -argument_list + + +> - - -type + + +explicitly_typed_local_variable_declaration - - -int + + +null_literal - - -nullable_value_type + + +method_header - - -value_type + + +stackalloc_expression - - -fixed_parameter + + +argument_list - - + + identifier type - - -weird + + +member_name - - -1 + + +( - - -argument + + +3 - - -} + + +statement - - -integral_type + + +invocation_expression - - -} + + +argument_value - - -, + + +type_argument - - -struct_declaration + + +explicitly_typed_local_variable_declarators - - -= + + +declaration_expression - - -fixed_parameters + + +args - - -( + + +method_header - - -t1 + + +primary_expression - - -explicitly_typed_local_variable_declarators + + +; - - -M1 + + +!= - - -ref_method_modifiers + + +[ - - -} + + +identifier - - -; + + +rank_specifier - - -namespace_or_type_name + + +) - - -tuple_element + + +expression - - -non_array_type + + +parameter_list - - -ref + + +{ - - -explicitly_typed_local_variable_declarator + + +primary_expression - - -statement_expression + + +fixed_size_buffer_declarator - - -null_literal + + +switch_section - - -a + + +where - - -block + + +type - - -invocation_expression + + +argument_list - - + + identifier - - -null - - - -type_argument_list - - - -argument_list + + +type - - -method_body + + +literal - - -true + + +parameter_list - - -ref + + +method_modifiers - - -method_declaration + + +{ - - + + statement_expression - - -tuple_element - - - -CSharp71 + + +( - - -pointer_type + + +struct_member_declaration - - -) + + +member_name - - -{ + + +literal - - -, + + +primary_expression - - -implicitly_typed_local_variable_declarator + + +identifier - - -expression_statement + + +1 - - -: + + +equality_expression - - -method_header + + +floating_point_type - - -t + + +null_conditional_member_access - - -identifier + + +readonly - - -method_modifiers + + +argument_list - - -{ + + +true - - -statement_expression + + +contextual_keyword - - -string + + +value_type - - -( + + +variable_declarator - - -local_variable_declaration + + +argument_value - - -( + + +int - - -} + + +Hello2 - - -var + + +) - - -c + + +argument explicit_anonymous_function_signature - - -ref - - - -arg + + +struct_member_declaration - - -identifier + + +* - - -; + + +invocation_expression - - -identifier + + +local_variable_declaration - - -new + + +type - - -statement + + +method_modifiers - - -identifier + + +type - - -multiplicative_expression + + +class_member_declaration - - -type + + +expression_statement - - -boolean_literal + + +method_header - - -) + + +switch_block - - + + identifier - - -myFixedField + + +integral_type - - + + +IndexingMovableFixed + + + identifier - - -local_variable_declaration + + +Select - - -statement_list + + +expression_statement + + + +ref + + + +1 - - -operator_modifier + + +static - - -statement_expression + + +binary_operator_declarator - - -declaration_statement + + +integral_type - - -> + + +argument_value - - -{ + + +. - - -class_type + + +( - - -; + + +method_header - - -return_type + + +member_access - - -conditional_expression + + +parameter_mode_modifier - - -( + + +block - - -async + + +int - - + + , - - -( + + +struct_declaration - - -} + + +if_statement - - -; + + +identifier - - -var + + +non_nullable_value_type - - -type + + +local_variable_declaration - - -identifier + + +ref_indexer_body - - -type_argument + + +object_creation_expression - - -argument + + +; - - -declaration_statement + + +anonymous_function_signature - - -literal + + +) - - -{ + + +} - - -void + + +explicitly_typed_local_variable_declarators - - -parameter_list + + +> - - -primary_expression + + +true - - + + +local_variable_declaration + + + identifier - - -class + + +integral_type - - + + ; - - -, + + +) - - -argument_list + + +operator_modifier + + + +member_access + + + +identifier + + + +identifier struct - - -r1 + + +Func - - -method_modifier + + +statement_list - - -argument_name + + +tuple_type - - -integral_type + + +) - - -type + + +; - - -ref + + +] - - -content + + +M1 - - -method_modifier + + +Vector3 - - -] + + +method_modifiers - - -; + + +class_body - - -in + + +relational_expression - - -, + + +Hello - - -fixed_parameter + + +literal - - -x + + +indexer_declaration - - -return_type + + +int - - -local_variable_initializer + + +) - - -a + + +argument - - -Span + + += - - -? + + +invocation_expression - - -integral_type + + +implicitly_typed_local_variable_declarator - - -local_variable_declaration + + +identifier - - -stackalloc_element_initializer + + +statement_list - - + + } - - -identifier + + +invocation_expression - - -variable_initializer + + +literal - - -2 + + +literal - - -method_declaration + + +member_name - - -unary_expression + + +] - - -identifier + + +type - - -element_access + + +int - - + + identifier - - -contextual_keyword - - - -simple_designation + + +int - - -+ + + +var - - -IndexingMovableFixed + + +{ - - -statement_list + + +integral_type - - -primary_expression + + +} - - -c + + +( - - -unary_expression + + +class_declaration - - -. + + +ref_kind - - -declaration_statement + + +type - - -assignment + + +literal - - -readonly + + +local_variable_initializer - - -primary_expression + + +variable_initializer - - -expression + + +identifier - - -assignment + + +argument - - -v1 + + +member_name - - -+ + + +declaration_statement - - -f1 + + +expression_statement - - -Span + + +tuple_expression - - -{ + + +[ - - -unsafe + + +y - - -return_statement + + +static - - + + identifier - - -argument_value + + +identifier - - -arg + + +t1 - - -Task + + +statement - - + + local_function_declaration - - -Func - - - -] + + +50 - - + + identifier - - -T + + +1 - - -local_variable_declaration + + +statement_expression - - -return + + +statement_list - - -struct_declaration + + +t - - -] + + +parameter_mode_modifier - - -unary_expression + + +identifier - - -literal + + +name - - -predefined_type + + +} - - -null_coalescing_expression + + +) - - -class_member_declaration + + +fixed_parameter - - -: + + +member_name - - -identifier + + +) - - + + identifier - - -+ - - - -f2 - - - -additive_expression - - - + + argument - - -identifier - - - -type_argument_list + + +< - - -{ + + +statement_list - - -DoSomething + + +ref - - -primary_expression + + +type_argument - - -else + + +item - - -type + + +member_access - - -StackallocArrayInitializer + + +> - - -? + + +argument_list - - -null_conditional_member_access + + +static - - -expression_statement + + +struct_member_declaration - - -identifier + + +array_type - - -int + + +argument_name - - -expression + + +) - - -identifier + + +unsafe - - -unmanaged_type + + +explicitly_typed_local_variable_declarators - - -type + + +class_member_declaration - - -statement_expression + + +( - - -Select + + +fixed_parameters - - -declaration_statement + + +== - - -ref_method_modifier + + +> - - -return_type + + +( - - -implicitly_typed_local_variable_declaration + + +additive_expression - - -default + + +local_variable_initializer - - -type + + +integral_type - - -isEmployed + + +int - - -ref + + +relational_expression - - + + identifier - - -conditional_or_expression - - - -argument_value + + +fixed_statement - - -type + + +lambda_expression - - -; + + +member_name - - + + identifier - - -local_variable_type + + +, - - -argument_list + + +statement_expression - - -= + + +v1 - - + + literal - - -explicitly_typed_local_variable_declarators - - - -, + + +multiplicative_expression - - -type + + +contextual_keyword - - -; + + +primary_expression - - -type_argument + + +statement_expression - - -explicitly_typed_local_variable_declaration + + +identifier - - -literal + + +return_type - - -argument_name + + +contextual_keyword - - -identifier + + +integral_type - - -} + + +( - - -lambda_expression + + +> - - -argument_name + + +F - - -fixed_parameter + + +int - - -"B" + + +} - - -; + + +ref_kind - - -method_modifiers + + +type - - -) + + +void - - -expression_statement + + +struct_member_declaration - - -switch_statement + + +type - - -block + + +additive_expression - - -local_variable_declaration + + +: - - -} + + +implicitly_typed_local_variable_declaration - - -type_argument + + +simple_designation - - -explicitly_typed_local_variable_declarator + + +anonymous_function_body - - -class_declaration + + +primary_expression - - -assignment_operator + + +identifier - - -namespace_or_type_name + + +} - - -expression_statement + + +multiplicative_expression - - -identifier + + +void - - -1 + + +field_modifier - - -class_member_declaration + + +identifier - - + + tuple_type_element - - -class_member_declaration + + +identifier - - -argument + + +value_type - - -integral_type + + +embedded_statement - - -unsafe + + +{ - - -primary_expression + + +identifier - - -10 + + +member_access - - -struct_member_declaration + + +{ - - -literal + + +, - - -argument_value + + +r2 - - -identifier + + +method_body - - -type + + +0b1_0_1 - - -] + + +0 - - -identifier + + +member_name - - -=> + + +personName - - -explicitly_typed_local_variable_declarators + + +} - - -explicitly_typed_local_variable_declaration + + +( - - -local_variable_declaration + + +) - - -non_array_type + + +fixed_parameter - - -fixed_parameters + + +ref_method_modifier - - -G + + +( - - -] + + +type_argument - - -. + + +T - - -class_member_declaration + + +alternative - - + + identifier - - + + +, + + + identifier - - -parameter_list + + +< - - -T + + +unmanaged - - -switch_label + + +fixed_size_buffer_declarators - - -primary_expression + + +local_variable_initializer - - -multiplicative_expression + + +block - - -type_argument_list + + +block - - -condition + + +expression - - -) + + +Choice - - -"A" + + +c - - -identifier + + +variable_reference - - -namespace_or_type_name + + +myFixedField - - -statement + + +class_member_declaration - - -local_function_header + + +( - - -statement + + +multiplicative_expression - - -DigitSeparators + + +, - - -expression_statement + + +myFixedField - - -ref + + +method_modifier - - -int + + +type - - -, + + +argument - - -== + + +identifier - - -return_type + + +invocation_expression - - -, + + +tuple_element - - -void + + ++ - - -method_declaration + + +local_function_header - - -( + + +unmanaged - - -2 + + +type - - -DoSomething + + +i - - -multiplicative_expression + + +ref_method_modifier - - -type_argument_list + + +local_variable_initializer - - + + +class_declaration + + + identifier - - -v2 + + +argument - - -identifier + + +return_type - - -out + + +primary_expression - - -identifier + + +integral_type - - -implicitly_typed_local_variable_declarator + + +relational_expression - - + + identifier - - -) - - - -method_header + + +method_modifiers - - -personName + + += - - + + statement - - -: - - - + + ) - - -identifier + + +class - - -public + + +parenthesized_expression - - -) + + +; - - -method_header + + +TupleRecognize - - + + identifier - - -] - - - -type_argument - - - -method_modifier + + +explicitly_typed_local_variable_declaration - - -boolean_literal + + +constant_expression - - -invocation_expression + + +variable_reference - - -i + + +declaration_statement - - -expression + + +argument_value - - -} + + +stackalloc - - -[ + + +parameter_modifier - - -method_modifiers + + +identifier - - -primary_expression + + +=> - - -ref_method_body + + +parameter_modifier - - -< + + +; - - -] + + +local_variable_initializer - - -statement_expression + + +method_body - - -identifier + + +; - - -block + + +ReadonlyRef2 - - -] + + += - - -NonTrailingNamedArguments + + +in - - + + identifier - - -v1 + + +isEmployed - - -method_header + + +content - - -type + + +null_literal - - -primary_expression + + +fixed - - -namespace_member_declaration + + +invocation_expression - - -, + + +condition - - + + ) - - -await_expression - - - -parameter_list - - - -< + + +class_member_declaration - - -int + + +return_type - - -equality_expression + + +; - - -[ + + +null_literal - - -ref + + +method_body - - -[ + + +embedded_statement - - -integral_type + + +invocation_expression - - -block + + +await - - -explicit_anonymous_function_parameter + + +type_argument - - -arr + + +identifier - - -member_name + + +fixed_parameter - - -namespace_or_type_name + + +multiplicative_expression - - -, + + +ref_method_modifier - - -item + + +class_type - - + + identifier - - -( - - - -throw - - - -class_member_declaration - - - -integral_type + + +if_statement - - -argument + + +fixed_parameter - - -, + + +declaration_expression - - + + { - - -default_literal - - - -method_body + + +3 - - -variable_declarators + + +tuple_type - - -struct_modifier + + +identifier - - -void + + +member_access - - -< + + +tuple_type_element - - -+ + + +: - - -method_header + + +: - - -true + + +statement_list - - + + +name + + + identifier - - -ref + + +pointer_type - - -local_variable_initializer + + +{ - - -integral_type + + +stackalloc_element_initializer - - -block + + +argument_list - - + + +struct_body + + + { - - -switch_label + + +invocation_expression - - -ref_kind + + +identifier - - -relational_expression + + +, - - -method_declaration + + +] - - -explicitly_typed_local_variable_declarators + + +return_type - - + + +null + + + identifier - - -i + + +identifier - - -struct + + +fixed_parameter - - + + argument - - -i + + +) - - -struct_member_declaration + + +; - - -expression_statement + + +( - - -class_member_declaration + + +literal - - -, + + +default - - -class_body + + +local_variable_declaration - - -element_access + + +1 - - -method_modifiers + + +null_coalescing_expression - - -statement_expression + + +method_body - - -literal + + +; - - -block + + +( - - -ref_method_modifier + + +parameter_list - - + + +member_name + + + statement - - -res + + +DoSomething - - -{ + + +string - - -integral_type + + +0x1_2_3 - - + + +( + + + identifier - - -array_type + + +default_literal - - -method_body + + +; - - -identifier + + +result - - -int + + +method_declaration - - -statement_expression + + +0 - - -explicitly_typed_local_variable_declarator + + +type + + + ++ + + + +type + + + +identifier + + + +f3 - - -int + + +identifier - - -nullable_type_annotation + + +value2 - - -: + + +age - - -( + + +v1 - - -primary_expression + + +1_000.111_1e-1_000 - - + + identifier - - + + identifier - - -0 + + +return_type - - -age + + +int - - -literal + + +identifier - - -parameter_modifier + + +literal - - -fixed_parameters + + +invocation_expression - - + + identifier - - -struct_declaration + + +namespace_member_declaration - - -invocation_expression + + +local_variable_initializer - - -, + + +1 - - -myFixedField + + +operator_declarator - - -argument_list + + +, - - -ref_method_body + + +) - - -; + + +implicitly_typed_local_variable_declarator - - -type_argument + + +ref_local_variable_declarator - - -identifier + + +method_header - - + + identifier - - -null_coalescing_expression - - - -alternative + + +namespace_or_type_name - - -method_declaration + + +? - - -; + + +primary_expression - - -. + + +primary_expression - - -( + + +expression_statement - - + + identifier - - -argument + + +simple_type - - -primary_expression + + +ref - - -identifier + + +name - - -integral_type + + +0b10011 - - + + identifier - - -; + + +explicitly_typed_local_variable_declarator - - -type + + +relational_expression - - -ref_local_variable_declarator + + +int - - -( + + +literal - - -0 + + +parenthesized_expression - - -argument + + +bool - - -anonymous_function_signature + + +ref + + + +primary_expression + + + +equality_expression + + + +statement_list + + + +literal - - -= + + +) - - -v1 + + += - - -bin + + +explicitly_typed_local_variable_declaration - - -identifier + + +} - - -; + + +when - - -parameter_list + + +a - - + + identifier - - -+ + + +v2 - - -method_header + + +TKey - - -identifier + + +0 - - -{ + + +integral_type - - -t + + +b - - -class_type + + +; - - -[ + + +) - - -v1 + + +) - - -s + + +alternative - - -+ + + +identifier - - -invocation_expression + + +type - - -( + + +, - - -variable_reference + + +} - - + + +int + + + identifier - - -tuple_type_element + + +Test - - -parameter_mode_modifier + + +additive_expression - - -return_type + + +integral_type - - -z + + +Mutate - - -int + + +otherArr - - -. + + +statement - - -ref + + +declaration_statement - - -( + + +default - - -DoSomething + + +fixed_pointer_declarator - - + + primary_expression - - -method_header + + +int - - -identifier + + +parameter_list - - -integral_type + + +multiplicative_expression - - -void + + +statement - - -{ + + +=> - - -local_variable_declaration + + +identifier - - + + literal - - -parameter_list - - - -argument_name - - - -{ + + +local_variable_declaration - - -literal + + +identifier - - -( + + +} - - -, + + += - - -TupleEquality + + +res - - -local_function_body + + +T - - -identifier + + +[ - - + + identifier - - -( + + +method_declaration - - -identifier + + +, - - -> + + +declaration_statement - - -1 + + +block - - -identifier + + +namespace_member_declaration - - -argument_value + + +public - - -method_modifiers + + +argument - - + + ; - - -primary_expression - - - -is + + +struct - - -age + + +additive_expression - - -( + + +class_member_declaration - - -args + + +member_access - - + + identifier - - -return_type - - - -r + + +fixed_pointer_declarators - - -invocation_expression + + +} - - -( + + +identifier - - -local_variable_initializer + + +666 - - -identifier + + +stackalloc_initializer_element_list - - -result + + +literal - - -tuple_element + + +0b1001_1010_0001_0100 - - -type + + +{ - - -identifier + + +( - - -method_body + + +statement - - + + identifier - - -( + + ++ - - -declaration_statement + + +statement - - -constant_expression + + +statement_list - - -argument_list + + +literal - - + + identifier - - -parameter_mode_modifier + + +explicitly_typed_local_variable_declaration - - -stackalloc_element_initializer + + += - - -method_body + + +local_variable_declaration - - -t + + +fixed_parameter - - -primary_expression + + +) - - -X + + +argument_list - - -stackalloc_element_initializer + + +return_type - - -stackalloc_initializer_element_list + + +} + + + +invocation_expression + + + +identifier + + + +b - - -IndexingMovableFixed + + += - - -type + + +expression - - + + expression - - -void + + +arg - - + + ) - - -0b10011 - - - -PatternBasedFixed - - - -) + + +stackalloc_initializer - - + + block - - -relational_expression + + +type - - -integral_type + + +statement - - -member_name + + +stackalloc_element_initializer - - -) + + +type_parameter - - + + +literal + + + statement - - -identifier + + +simple_type - - -statement + + +( - - -fixed_parameter + + +33_554_432 - - + + +struct_declaration + + + +expression_statement + + + +element_access + + + +0b101 + + + ] - - -> + + +member_name - - -argument_name + + +tuple_type_element - - -await_expression + + +fixed_size_buffer_declaration - - -integral_type + + +identifier - - -explicitly_typed_local_variable_declaration + + +return_statement - - -member_access + + +literal - - -= + + +type - - -return_type + + +B - - -method_body + + +class_member_declaration - - -statement + + +primary_expression - - -byteArray + + +default - - -identifier + + +explicitly_typed_default - - -argument_list + + ++ - - -switch + + +argument_value - - -integral_type + + +equality_expression - - + + +literal + + + method_declaration - - -literal + + +; - - -c + + +type_argument - - + + +identifier + + + public - - -. + + +identifier - - -LocalFunctions + + +primary_expression - - -, + + +namespace_or_type_name + + + +identifier + + + +bin - - -identifier + + +member_access - - -, + + +ref_return_type - - -ref_method_body + + +boolean_literal - - -; + + +{ - - + + +void + + + ( - - -; + + +declaration_statement - - + + +public + + + literal - - -Span + + +] - - -) + + +additive_expression - - -expression_statement + + +=> - - -type + + +( - - -. + + +X - - -= + + +identifier - - -block + + +declaration_statement - - -a + + +expression - - -statement + + +return_type - - + + block - - -member_access + + +, - - -void + + +ConditionalRef - - + + identifier - - -statement + + +fixed_parameter - - -identifier + + +. - - -M1_Trace + + +?? - - -identifier + + +local_variable_initializer - - -identifier + + +span - - -argument_name + + +literal - - -( + + +primary_expression - - -identifier + + +explicitly_typed_local_variable_declarators - - -type + + +parameter_modifier - - -integral_type + + +Vector3 - - -} + + +stackalloc_initializer - - -identifier + + +, - - -int + + +return_type - - -stackalloc_element_initializer + + +variable_reference - - -equality_expression + + +: - - -{ + + +[ - - -method_declaration + + +argument - - -primary_expression + + +declaration_statement - - -ref_method_modifier + + +identifier - - -return_type + + +method_body - - -method_declaration + + +ref_local_variable_declarator - - -; + + +method_header - - -ref_method_modifier + + +method_body - - -int + + +integral_type - - -expression + + +> - - -class_member_declaration + + +local_variable_declaration - - -assignment + + +) - - -( + + +case_guard - - -type + + +< - - -Hello + + +declaration_statement - - -statement_list + + +method_header - - -argument_list + + +namespace_or_type_name - - + + } - - -res + + +unary_expression - - -b + + +stackalloc_initializer - - -) + + +static - - -argument + + +declaration_statement - - -void + + +identifier - - -ref_method_modifier + + +( - - -type_argument + + +; - - -identifier + + +Print - - -type_argument_list + + +member_name - - -= + + +identifier - - -return_statement + + +identifier - - -local_function_header + + +var - - -null_literal + + +var - - -0b101 + + +ref_method_body - - -int + + +method_declaration - - + + identifier - - -literal + + +) - - -explicitly_typed_local_variable_declarator + + +Vector3 - - -anonymous_function_parameter_modifier + + +; - - -int + + +type - - -( + + +method_header - - -Span + + +ref_kind - - -3 + + +local_variable_declaration - - -C + + +stackalloc_element_initializer - - + + +; + + + +explicitly_typed_local_variable_declaration + + + ) - - -( + + +method_modifiers - - -ref_kind + + +multiplicative_expression - - -TKey + + +0b_1_0_1 - - -boolean_literal + + +0 - - -explicitly_typed_local_variable_declarator + + +( + + + +) + + + +v1 + + + +y - - -local_variable_declaration + + +argument - - -member_access + + +predefined_type - - -} + + +is - - -ref + + +parameter_list - - -parameter_modifier + + +invocation_expression - - -= + + +identifier - - -+ + + +public - - -int + + +statement - - -tuple_type_element + + +stackalloc_element_initializer - - -additive_expression + + +Span - - + + +identifier + + + declaration_statement - - -class_member_declaration + + +method_body - - -statement_list + + +identifier - - + + +int + + + +Vector3 + + + identifier - - -method_modifiers + + +in - - -= + + +< - - -) + + +async - - -Blittable + + +method_modifiers - - -r2 + + +explicitly_typed_local_variable_declarator - - -integral_type + + +C - - -fixed_statement + + +IndexingMovableFixedFields ref_method_modifier - - -return_type - - - -ref_method_modifier - - - + + = - - -primary_expression - - - -variable_reference - - - -: - - - -) - - - -; - - - -void + + +identifier - - -( + + +index - - -primary_expression + + +. - - -method_declaration + + +args - - -[ + + +t2 - - -= + + +t - - -) + + +declaration_expression - - -} + + +statement - - -identifier + + +default - - -class_type + + +declaration_statement - - -identifier + + +ref_method_modifier - - -local_variable_declaration + + +block - - -Type + + +parameter_modifier - - -class_member_declaration + + +argument_list - - -) + + +type - - -statement_list + + +identifier - - -NullReferenceException + + +shift_expression - - -; + + +array_type - - -b + + +identifier - - -Y + + +case_guard - - -stackalloc_expression + + +type_argument_list - - -integral_type + + +identifier - - -return_type + + +Hello - - -argument_value + + +statement - - + + identifier - - -consequence + + +} - - -local_variable_declaration + + +fixed_parameter - - -int + + +TValue - - -identifier + + +unsafe_modifier - - + + identifier - - -1 + + +Z - - -< + + +isEmployed - - -) + + +expression - - -index + + +identifier - - -, + + +s - - -literal + + +( - - -== + + +null_conditional_member_access - - -ConditionalRef + + +primary_expression - - -name + + +; - - -( + + +case - - -method_declaration + + +block - - -rank_specifier + + +parameter_mode_modifier - - + + +explicitly_typed_local_variable_declarators + + + +literal + + + +isEmployed + + + identifier - - -{ + + +method_modifiers - - -literal + + +type_argument_list - - -{ + + +invocation_expression - - -; + + +argument - - -member_name + + +identifier - - -integral_type + + +identifier - - -isEmployed + + +; - - -declaration_statement + + +local_variable_declaration - - + + type - - -literal + + +local_variable_declaration - - -( + + +method_body - - -= + + +identifier - - + + identifier - - -. + + +local_function_modifier + + + +in + + + +element_access - - -parameter_modifier + + +boolean_literal - - -declaration_statement + + +type - - -implicitly_typed_local_variable_declaration + + +; - - -unsafe_modifier + + +{ - - -int + + +, - - -f3 + + +) - - -[ + + +( - - -identifier + + +( - - -identifier + + +struct_modifier - - + + identifier - - -span + + +method_modifiers - - -e + + +( - - -equality_expression + + +literal - - -expression + + +ref - - + + statement_expression - - -pattern + + +primary_expression - - -type_argument_list + + +variable_reference - - -fixed_parameter + + +explicitly_typed_local_variable_declaration - - -. + + +declaration_statement - - -member_access + + +statement - - -name + + +switch - - -where + + +int - - -T + + +integral_type - - -return_type + + +unary_expression - - -declaration_expression + + +int - - -method_declaration + + +< - - + + = - - -multiplicative_expression - - - -buffer_element_type - - - -identifier - - - -. + + +equality_expression - - -primary_expression + + +v2 - - -[ + + +explicitly_typed_local_variable_declaration - - -int + + +literal - - -ref_method_modifier + + +multiplicative_expression - - -parameter_mode_modifier + + +r - - -int + + +res - - -method_modifiers + + +identifier - - -stackalloc_element_initializer + + +integral_type - - -readonly + + +ptr - - -; + + +class_declaration - - -) + + +( - - -T + + +invocation_expression - - + + ; - - -i + + +real - - -=> + + +fixed_parameter - - -{ + + +relational_expression - - -public + + +explicitly_typed_local_variable_declaration - - -identifier + + +personName - - -H + + +conditional_or_expression - - -byte + + +variable_reference - - -default_argument + + +member_name - - -int + + +) - - -( + + +} - - -local_variable_type + + +ref - - -explicitly_typed_local_variable_declarator + + +implicitly_typed_local_variable_declarator - - -parameter_mode_modifier + + +type_parameter_constraints - - -argument_list + + +( - - -T + + +] - - -type_parameter_constraints_clause + + +member_name - - -local_variable_declaration + + +} - - -identifier + + +struct_declaration - - -prog + + +return_type - - -member_access + + +A - - -v + + +age - - -{ + + +identifier - - -namespace_or_type_name + + +null_literal - - -if + + +i - - + + string - - -CSharp72 + + +( - - -member_name + + +identifier - - -personName + + +statement_list - - -} + + +T - - -indexer_declaration + + += - - -identifier + + +class_member_declaration - - -literal + + +t1 - - -expression + + +identifier - - -) + + +class - - -stackalloc_element_initializer + + +operator_body - - + + . - - -type + + +public - - -ref + + +lambda_expression - - -fixed_size_buffer_declaration + + +invocation_expression - - -fixed_size_buffer_declarator + + +x - - -type + + +ref_method_modifier - - -unmanaged + + +. - - + + identifier - - -tuple_type - - - -statement + + +identifier - - -type + + +tuple_element - - -break_statement + + +] - - -Hello + + +implicitly_typed_local_variable_declarator - - -out + + +identifier - - -argument_value + + +CSharp70 - - -; + + +block - - -[ + + +explicitly_typed_local_variable_declarators - - -) + + +ref_method_modifier - - -invocation_expression + + +variable_reference - - -; + + +return_type - - -Hello + + +unsafe - - -fixed_parameter + + +a - - -= + + +tuple_type_element - - -) + + +return - - -1 + + +fixed_parameter - - -method_declaration + + +} - - -+ + + +identifier - - + + identifier - - -hex + + +public - - + + identifier - - -identifier + + +decorated_type_parameter - - -{ + + +} - - -( + + +[ - - -identifier + + +] - - -overloadable_binary_operator + + +v1 - - -) + + +int - - -type_parameter + + +break_statement - - + + +local_variable_initializer + + + identifier - - -) + + +static - - -. + + +TupleEquality - - -tuple_type_element + + +( - - -type + + +expression - - -tuple_expression + + +int - - -= + + +ref_method_modifier - - -identifier + + +( - - -primary_expression + + +{ - - -namespace_member_declaration + + +: - - -explicitly_typed_local_variable_declarators + + +block - - -compilation_unit + + +method_modifier - - -method_body + + +tuple_element + + + +tuple_element + + + +expression + + + +CSharp73 - - + + +. + + + member_name - - -; + + +r1 - - -return_type + + +[ - - -= + + +local_variable_declaration - - -invocation_expression + + +; - - -variable_reference + + +explicitly_typed_local_variable_declarators - - + + identifier - - -PatternMatching + + +myFixedField - - -foo + + +stackalloc_element_initializer - - -) + + +, ( - - -method_modifiers - - - -void - - - -identifier + + +int - - -explicitly_typed_ref_local_variable_declaration + + +. - - -primary_expression + + +true - - -0 + + +type - - -; + + +class - - -primary_expression + + +statement_list - - -struct_member_declaration + + +: - - -multiplicative_expression + + +integral_type - - -multiplicative_expression + + +TryParse - - -statement + + +prog - - -class_body + + +) - - -in + + +relational_expression - - -method_modifiers + + +; - - -> + + +implicitly_typed_local_variable_declaration - - -!= + + +tuple_type_element - - -if + + +identifier - - -declaration_statement + + +statement - - -) + + +, - - -static + + +integral_type - - -DoSomething + + +argument_list - - -fixed_parameter + + +type - - -statement + + +integral_type - - -( + + +method_header - - -identifier + + +, - - -return_type + + +method_body - - -identifier + + +ref_method_modifier - - + + = - - -{ + + +statement_expression - - -declaration_pattern + + +tuple_type_element - - -fixed_parameter + + +method_declaration - - -argument_list + + +additive_expression + + + +member_access - - -unmanaged_type + + +struct_member_declaration - - -local_variable_declaration + + +Type - - -; + + +) - - -literal + + +method_declaration - - -implicitly_typed_local_variable_declaration + + +type - - -invocation_expression + + +) - - -DoSomething + + +argument_name - - + + identifier - - -; + + +( - - -statement + + +1 - - -, + + +return_type - - -identifier + + +decorated_type_parameter - - -{ + + +parameter_list - - -argument_list + + +, - - -Vector3 + + +argument_list - - + + identifier - - -class_member_declaration + + +identifier - - -] + + +ref_method_modifiers - - -stackalloc_expression + + +identifier - - -tuple_element + + +int - - -( + + +identifier - - -argument + + +ref_method_modifier - - -. + + +statement_list - - -method_modifiers + + +expression - - -Z + + +var - - -: + + +integral_type - - -lambda_expression + + +readonly - - -block + + +argument - - -statement + + +explicitly_typed_local_variable_declarators - - -, + + +identifier - - -public + + +in additive_expression - - -Task + + +local_variable_initializer - - -class + + +{ - - -FromResult + + +statement_expression - - -T + + +identifier - - + + +E + + + +} + + + identifier - - -static + + +identifier - - -stackalloc + + +) - - -} + + +primary_expression - - -explicitly_typed_local_variable_declarator + + +argument_list - - -0 + + +] + + + +) + + + +{ - - -double + + +{ - - -new + + +statement_list - - -equality_expression + + +. - - -member_access + + +statement_expression - - -return + + +consequence - - -additive_expression + + +) - - -method_header + + ++ - - -ref_method_modifier + + +ref_return_type - - -) + + +{ - - -) + + +identifier - - -< + + +Y - - -predefined_type + + +isEmployed - - -argument_list + + +declaration_expression - - -> + + +return_type - - -integral_type + + +return_type - - -tuple_type + + +; - - -tuple_expression + + +class_member_declaration - - -} + + +) - - -type_argument_list + + +identifier - - -operator + + +implicitly_typed_local_variable_declaration - - -ThrowExpression + + +readonly - - + + identifier - - -expression + + +method_body - - -expression + + +{ - - -argument + + +var - - -local_variable_declaration + + +tuple_element - - -member_access + + +] - - -int + + +element_access - - -tuple_type_element + + +c - - -anonymous_function_body + + +b - - -{ + + +class_member_declaration - - -int + + +argument_name - - -member_name + + +pattern - - -statement_list + + +block - - -string + + +) - - -ref_method_modifier + + +statement_expression - - -fixed_parameter + + +statement - - -arr + + +identifier - - -2 + + +argument - - -stackalloc + + +parameter_list - - -: + + +literal + + + +integral_type + + + +) + + + +expression_statement - - -statement_list + + +integral_type - - -invocation_expression + + +type - - -unary_expression + + +primary_expression - - -explicitly_typed_local_variable_declaration + + +additive_expression - - + + +method_body + + + identifier - - -method_header + + +primary_expression - - -element_access + + +type - - -nullableResult + + +tuple_type_element - - -parameter_modifier + + +readonly - - -simple_type + + +identifier - - -* + + +string - - -case_guard + + +identifier - - -null_coalescing_expression + + +} - - -type_argument + + +fixed_size_buffer_modifier - - -literal + + +type - - + + : - - -equality_expression + + +string - - -) + + +literal - - -conditional_expression + + +; - - -argument_value + + +identifier - - -namespace_or_type_name + + +ref - - -type + + +nineteen - - -type + + +ref - - + + ref_method_modifier - - -ref_method_modifiers + + +identifier - - -ref_return_type + + +var - - -( + + +statement - - -decorated_type_parameter + + +block - - -method_modifiers + + +string - - -; + + +a - - -variable_reference + + +method_declaration - - -in + + +2 - - -identifier + + +D - - -Print + + +parameter_modifier - - -type_argument_list + + +boolean_expression - - -( + + +ref - - -argument_list + + +identifier - - -embedded_statement + + +123 - - -literal + + +} - - -ref_kind + + +identifier - - -stackalloc_expression + + +void - - -Hello2 + + +DoSomething + + + +Span + + + +) - - -type + + +parameter_list - - -{ + + +method_declaration - - -argument_value + + +) - - -condition + + +argument - - -fixed_parameter + + +Span - - -class_declaration + + +statement - - -argument_list + + +, - - -parameter_list + + +( - - -true + + +literal - - -a + + +] - - -local_variable_declaration + + +int - - -assignment_operator + + +int - - + + ) - - -ptr + + +additive_expression - - -method_header + + +PatternMatching - - -integral_type + + += - - -argument_list + + +. - - -identifier + + +declaration_statement - - -ref_return_type + + +( - - -v1 + + +byteArray - - -identifier + + +integral_type - - -, + + +a - - -declaration_expression + + +type_argument_list - - -bool + + +[ - - -method_header + + +; - - + + member_name - - -relational_expression - - - -] - - - + + { - - + + identifier - - -+ + + +statement_expression - - -) + + +byte - - -local_variable_declaration + + +expression_statement explicitly_typed_local_variable_declaration - - -? + + += - - -invocation_expression + + +expression_statement - - -public + + +T - - -int + + +integral_type - - -} + + +declaration_statement - - -( + + +CSharp72 + + + +identifier + + + +arr + + + +argument + + + +stackalloc_expression + + + +class_type + + + +block + + + +type_argument_list + + + +class_body - - -fixed_parameter + + +void - - -, + + +int - - -member_name + + +< - - -fixed_pointer_declarator + + +type_argument - - -{ + + +( - - -element_access + + +class_body - - -local_variable_initializer + + +; - - -TryParse + + +fixed_parameters - - -null_coalescing_expression + + += - - -expression + + +statement - - -otherArr + + +literal - - -( + + +; - - -class + + +type - - -explicitly_typed_local_variable_declarators + + +type_argument_list - - -parameter_list + + +non_array_type - - -implicitly_typed_local_variable_declarator + + +default - - -method_declaration + + +[ - - -r1 + + +out - - -=> + + +primary_expression - - -( + + +, - - -member_access + + +ref_method_modifiers - - -identifier + + +Vector3 - - -anonymous_function_body + + +parameter_list - - -explicitly_typed_local_variable_declarator + + +identifier - - + + stackalloc - - -implicitly_typed_local_variable_declaration + + +literal - - -expression_statement + + +identifier - - -literal + + +public - - -return_type + + +} - - -operator_body + + +relational_expression - - -; + + +identifier - - -ref_method_modifier + + +( - - -integral_type + + +default_argument - - -Vector3 + + +< - - -int + + +stackalloc_element_initializer - - -local_function_body + + +ref_method_body - - -; + + +statement_list - - -r1 + + +identifier - - -class_member_declaration + + +int - - -integral_type + + +type - - -statement + + +method_header - - -Z + + +] - - -contextual_keyword + + +; - - -D + + +identifier - - -. + + +, - - -integral_type + + +literal - - -expression + + +literal - - -invocation_expression + + +stackalloc_expression - - -rank_specifier + + +explicitly_typed_local_variable_declaration - - -anonymous_function_body + + +method_declaration - - -struct + + +ref - - -lambda_expression + + +argument_list - - -ref_kind + + +declaration_pattern - - + + identifier - - -type - - - -parameter_list + + +; - - -parenthesized_expression + + +local_variable_initializer - - -class_member_declaration + + +if - - + + member_name - - -method_header + + +class_member_declaration - - + + identifier - - -CSharp73 + + +identifier - - -{ + + +primary_expression - - -when + + +NonTrailingNamedArguments - - -statement_list + + +local_variable_declaration - - -identifier + + +} - - -local_variable_initializer + + +ref_method_modifier - - -stackalloc_element_initializer + + +) - - -ref + + +ref_kind - - -identifier + + +explicit_anonymous_function_parameter_list - - -statement_list + + +local_variable_declaration - - + + identifier - - -( - - - -1_2_3 + + +tuple_element - - + + . - - -[ + + +variable_declarators - - -block + + +parameter_mode_modifier - - -identifier + + +embedded_statement - - -member_name + + +ThrowExpression - - -void + + +literal - - -= + + +primary_expression - - -local_variable_declaration + + +; - - -return_statement + + +; - - -identifier + + +, - - -method_body + + +literal - - -; + + +constant_expression - - -identifier + + +{ - - -local_function_declaration + + +tuple_expression - - -statement + + +void - - -static + + +int - - -consequence + + +return_type - - -identifier + + +primary_expression - - -identifier + + +void - - -, + + +DoSomething - - -identifier + + +type - - -identifier + + +method_declaration - - -class_member_declaration + + +literal - - -block + + +< - - -? + + +explicitly_typed_local_variable_declarator - - -} + + +class_body - - -contextual_keyword + + +int - - -variable_reference + + +identifier - - -ref + + +literal - - + + +; + + + statement - - -argument_list + + +explicitly_typed_local_variable_declarator - - -identifier + + +, - - -identifier + + +, - - + + type - - + + { - - -literal - - - -local_variable_declaration + + +statement - - -return + + +, - - + + identifier - - -ref + + +fixed_pointer_initializer - - + + +block + + + +argument_list + + + fixed_parameter - - + + +literal + + + identifier - - -( + + +> - - -identifier + + +type_argument - - -identifier + + +] - - -object_creation_expression + + +ref_method_modifiers - - -) + + +( - - -identifier + + +when - - -argument + + +namespace_or_type_name - - -list + + +expression - - -explicit_anonymous_function_parameter_list + + +: - - -equality_expression + + +method_header - - -} + + +integral_type - - -identifier + + +arr - - -public + + +type_argument_list + + + +explicitly_typed_local_variable_declarator + + + +tuple_expression - - -variable_reference + + +age - - -explicitly_typed_local_variable_declaration + + +stackalloc_element_initializer - - -stackalloc_expression + + +) - - -type + + +) + + + +null_coalescing_expression true - - -case - - - -member_name - - - -} - - - + + { - - + + identifier - - -alternative - - - + + identifier - - -additive_expression + + +identifier - - -isEmployed + + +explicitly_typed_local_variable_declarator - - -integral_type + + +public - - -stackalloc_initializer_element_list + + +statement - - -method_modifiers + + +variable_reference - - + + ; - - -r1 + + +primary_expression - - + + +Span + + + +method_modifiers + + + identifier - - -declaration_expression + + +class_member_declaration - - -) + + +ref_local_variable_declarators - - -Vector3 + + +( - - -identifier + + +method_modifier - - -+ + + +non_array_type - - -, + + +member_name - - -1_000.111_1e-1_000 + + ++ - - -0x1_2_3 + + +additive_expression - - + + identifier - - -object_creation_expression + + +block - - -expression + + +member_name - - -Task + + +ref - - + + +identifier + + + +, + + + method_header - - -explicitly_typed_local_variable_declarator + + +argument_list - - -LeadingSeparator + + +Z - - -declaration_statement + + +i - - -int + + ++ - - -) + + +integral_type - - + + identifier - - -tuple_expression + + +int - - -statement_list + + +relational_expression - - -declaration_statement + + +argument_list + + + +boolean_literal + + + +, + + + +nullable_value_type + + + +ref - - -int + + +invocation_expression - - -tuple_type + + +) - - + + ( - - -case_guard + + +; - - -method_header + + +tuple_type_element - - -argument + + +multiplicative_expression - - -33_554_432 + + +: - - -explicitly_typed_local_variable_declarators + + +statement_expression - - -integral_type + + +identifier - - -nineteen + + +anonymous_function_parameter_modifier - - -primary_expression + + +additive_expression - - -int + + +literal - - -v1 + + +identifier - - -type + + +b - - -stackalloc_initializer + + +3 - - -return_type + + +literal - - -var + + +X - - -? + + +default_literal - - -class_member_declaration + + +readonly - - -statement_list + + +) - - -IndexingMovableFixedFields + + +struct - - -identifier + + +) - - -statement + + +overloadable_binary_operator - - -} + + +Task - - -type + + +DefaultWithoutTypeName - - -0b_1_0_1 + + +? - - -} + + +statement_expression - - -ref_kind + + +argument - - + + +{ + + + ref - - -( + + +literal - - -public + + += - - -invocation_expression + + +integral_type - - -unmanaged_type + + +: - - -, + + +namespace_or_type_name - - -additive_expression + + +( - - -name + + +] - - -declaration_statement + + +X - - -Vector3 + + +identifier - - -declaration_statement + + +new - - -expression_statement + + +{ - - -local_variable_initializer + + +identifier - - -relational_expression + + +statement_list + + + +class_member_declaration - - -identifier + + +argument_value - - + + ( - - -ref + + +class_declaration - - -variable_reference + + +embedded_statement - - -0b1_0_1 + + +field_declaration - - + + +method_body + + + identifier - - -) + + +primary_expression - - -fixed_size_buffer_declarators + + +ref_local_variable_declarator - - -method_body + + +{ - - -explicitly_typed_local_variable_declarators + + +explicitly_typed_local_variable_declaration - - -identifier + + +expression - - -DefaultWithoutTypeName + + += - - -element_access + + +argument_list - - -int + + +var - - -dec + + +class_type - - -age + + +result - - -operator_declaration + + +this - - -3 + + +) - - -( + + +identifier - - -[ + + +type_argument - - -primary_expression + + +boolean_literal - - -= + + +( - - -< + + +0 - - -c + + +pointer_type - - -method_modifier + + +pattern - - -otherArr + + +; - - -local_variable_initializer + + +implicitly_typed_local_variable_declaration - - -identifier + + +member_name - - -declaration_statement + + +0x_1_2 - - -expression + + +explicitly_typed_local_variable_declarator - - -static + + +local_variable_initializer - - -} + + +return - - -public + + +equality_expression - - -multiplicative_expression + + +) - - -literal + + +statement - - -method_header + + +( - - -method_body + + +identifier - - -ReadonlyRef2 + + +declaration_statement - - -local_variable_declaration + + +invocation_expression - - -; + + +. - - -} + + +ref + + + +expression + + + +( - - -) + + +integral_type - - -type_parameter_constraints + + +statement - - -s + + +argument - - -in + + +== - - -explicitly_typed_local_variable_declaration + + +identifier - - -type + + +literal - - -type_argument + + +tuple_type - - -ref_indexer_body + + +type - - + + expression - - -block + + +literal - - -local_variable_declaration + + +T - - -variable_declarator + + +) - - -literal + + +) - - -explicitly_typed_local_variable_declaration + + +) - - + + identifier - - -class_member_declaration + + +fixed_parameter - - -break + + +{ - - -. + + +int - - -) + + +"B" - - -if + + +primary_expression - - -public + + +class_member_declaration - - + + identifier - - -) - - - -ref + + +in - - -fixed_parameter + + +identifier - - -element_access + + +identifier - - -statement_list + + +struct_body - - -[ + + +explicitly_typed_local_variable_declarator - - -statement_expression + + +} - - -expression + + +TryParse - - -v2 + + +( - - -; + + +type - - -[ + + +. - - -local_variable_type + + +return_type - - -0x_1_2 + + +expression_statement - - -} + + +unsafe_modifier - - -> + + +consequence - - -identifier + + +relational_expression - - -identifier + + +3 - - -) + + +method_header - - -statement + + +null - - -method_body + + +assignment_operator - - -( + + +statement_list - - -) + + +identifier - - -type + + +explicitly_typed_local_variable_declarator - - -. + + +: - - -primary_expression + + +argument_value - - -class_declaration + + +class_member_declaration - - -void + + +, - - -statement_list + + +identifier - - -method_body + + +Hello - - -embedded_statement + + +int - - -ref + + +ReadonlyRef1 - - -primary_expression + + +identifier - - -) + + +fixed_parameter - - -( + + +primary_expression - - -equality_expression + + +case - - -return_type + + +declaration_statement - - -local_function_modifier + + +member_access - - -literal + + +, - - -: + + +x - - -shift_expression + + +local_variable_initializer - - -parameter_mode_modifier + + +public - - -implicitly_typed_local_variable_declarator + + +stackalloc - - -Mutate + + +void - - -identifier + + +local_variable_declaration - - -public + + +namespace_or_type_name - - -{ + + +await_expression - - -literal + + +predefined_type - - -fixed_parameter + + +type - - -isEmployed + + +ref_method_modifier - - -explicitly_typed_local_variable_declarator + + +statement_expression - - -implicitly_typed_local_variable_declaration + + +( - - -> + + +true - - -relational_expression + + +expression_statement - - -statement + + +Task - - -var + + +tuple_type_element - - -Vector3 + + +FromResult - - -Guid + + +statement int - - -method_modifiers + + +identifier - - -> + + +0x1b_a0_44_fe - - -expression + + +. - - -0b1001_1010_0001_0100 + + +( - - -} + + +field_declaration - - -) + + +method_modifiers + + + +, + + + +dec + + + +r1 - - -when + + +integral_type - - -return + + +. - - -primary_expression + + +boolean_expression - - -literal + + +personName - - -statement + + +conditional_expression - - -declaration_statement + + +conditional_expression - - -member_access + + +argument - - -invocation_expression + + +identifier - - + + identifier - - -explicitly_typed_local_variable_declaration + + +local_variable_declaration - - -in + + +identifier - - -type + + +, - - -identifier + + +x - - -type_argument_list + + +stackalloc - - -identifier + + +tuple_type - - -666 + + +} - - -primary_expression + + +method_declaration - - + + +OutVar + + + identifier - - -declaration_statement + + +variable_reference - - -ref_local_variable_declarator + + +1 - - -parameter_list + + +method_header - - -literal + + +Vector3 - - -identifier + + +( - - -argument + + ++ - - -identifier + + +IndexingMovableFixed - - -identifier + + +int - - -var + + +; - - -null + + +v1 - - -default_literal + + +primary_expression - - -y + + +fixed_parameter - - -= + + +member_access - - -] + + +unary_expression - - -expr + + +expression - - -struct_member_declaration + + +statement_list - - -return + + +{ - - -; + + +public - - -: + + +Vector3 - - -args + + +personAge - - -tuple_type + + +fixed_parameter - - -int + + +argument_value - - -switch_label + + +fixed_parameter + + + +type_parameter_list + + + +public - + \ No newline at end of file From 8651d5bde81e218fc8b0b40baab66a0def9b59f5 Mon Sep 17 00:00:00 2001 From: Nigel-Ecma Date: Wed, 10 Sep 2025 15:57:02 +1200 Subject: [PATCH 8/8] Reposition new top-level clause & renumber --- admin/ECMA-TC49-TG2-New-Member-Orientation.md | 8 +- standard/README.md | 389 +++++++++--------- standard/arrays.md | 4 +- standard/attributes.md | 136 +++--- standard/basic-concepts.md | 22 +- standard/classes.md | 98 ++--- standard/clauses.json | 4 +- standard/conversions.md | 30 +- standard/delegates.md | 34 +- standard/documentation-comments.md | 2 +- standard/enums.md | 28 +- standard/exceptions.md | 18 +- standard/expressions.md | 380 ++++++++--------- standard/grammar.md | 109 ++--- standard/interfaces.md | 82 ++-- standard/lexical-structure.md | 14 +- standard/namespaces.md | 4 +- standard/patterns.md | 4 +- standard/portability-issues.md | 42 +- standard/ranges.md | 76 ++-- standard/statements.md | 36 +- standard/structs.md | 12 +- standard/types.md | 32 +- standard/unsafe-code.md | 126 +++--- standard/variables.md | 24 +- 25 files changed, 864 insertions(+), 850 deletions(-) diff --git a/admin/ECMA-TC49-TG2-New-Member-Orientation.md b/admin/ECMA-TC49-TG2-New-Member-Orientation.md index d13dd7717..c6044e925 100644 --- a/admin/ECMA-TC49-TG2-New-Member-Orientation.md +++ b/admin/ECMA-TC49-TG2-New-Member-Orientation.md @@ -24,7 +24,7 @@ Some years ago, we moved the spec source from MS Word to GitHub/md, and later th - Chair of ECMA TC49: This keeps him in touch with the Ecma Secretary General, the bi-annual General Assembly, and the associated Ecma Executive Committee (ExeComm). - Ecma liaison to ISO/IEC JTC/1 SC22 (programming languages, tools, and environments): For TC49 (C#, CLI, Eiffel) and TC39 (ECMAScript). - Background task: Rex has been creating formal feature specs from [MS’ specs](https://github.com/dotnet/csharplang/tree/main/proposals) for V9–14. The V9 ones are already in the repo as Draft PRs. The formal feature specs for versions beyond V9 are kept offline by Rex (with Jon and Bill also having copies). When V8 is completed and we start work on the V9 Draft PRs, Rex will make the V10 Draft PRs available. - + ## Official Document Home All meeting agendas and minutes are assigned numbers by Ecma admin staff, and are posted to the Ecma-hosted TG2 website to which all members have access. Draft versions of these documents are posted privately to members. @@ -37,7 +37,7 @@ To avoid that extra ISO step and to eliminate the 1-year delay, in December 2022 Ordinarily, Ecma approves new specs at its June and December General Assemblies (GAs). To get considered at one of those, we need to have a feature-complete and almost technically complete spec ready by mid-March or mid-September, respectively. If we submit a new version at any other time, rather than have it voted on via a letter ballot, it typcially waits until the next GA. That said, once TG2 completes a version it typically starts work on next one, as Draft PRs for that are already available. -If errors are found in a published spec, we do ***not*** make available a corrected version; corrections simply go into the next version. +If errors are found in a published spec, we do ***not*** make available a corrected version; corrections simply go into the next version. ## C# Formal Grammar @@ -48,11 +48,11 @@ Nigel is our resident grammar expert. The core ANTLR implementation doesn’t allow left recursion, although a C#-code-generating version does. Nigel made a tool to extract the grammar from the spec and to rearrange the grammar to get it to pass the ANTLR validator. - + ## Examples in the spec We have tools to extract the examples and compile them and execute them. (See https://github.com/dotnet/csharpstandard/blob/draft-v8/tools/README.md.) - + ## Status of Features in the Current Spec Draft For a given version *X*, see file v*X*-feature-tracker.md in https://github.com/dotnet/csharpstandard/tree/draft-v8/admin. diff --git a/standard/README.md b/standard/README.md index b602d9e61..f69577501 100644 --- a/standard/README.md +++ b/standard/README.md @@ -342,7 +342,8 @@ - [§12.8.12](expressions.md#12812-element-access) Element access - [§12.8.12.1](expressions.md#128121-general) General - [§12.8.12.2](expressions.md#128122-array-access) Array access - - [§12.8.12.3](expressions.md#128123-indexer-access) Indexer access + - [§12.8.12.3](expressions.md#128123-string-access) String access + - [§12.8.12.4](expressions.md#128124-indexer-access) Indexer access - [§12.8.13](expressions.md#12813-null-conditional-element-access) Null Conditional Element Access - [§12.8.14](expressions.md#12814-this-access) This access - [§12.8.15](expressions.md#12815-base-access) Base access @@ -369,85 +370,87 @@ - [§12.9.3](expressions.md#1293-unary-minus-operator) Unary minus operator - [§12.9.4](expressions.md#1294-logical-negation-operator) Logical negation operator - [§12.9.5](expressions.md#1295-bitwise-complement-operator) Bitwise complement operator - - [§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators) Prefix increment and decrement operators - - [§12.9.7](expressions.md#1297-cast-expressions) Cast expressions - - [§12.9.8](expressions.md#1298-await-expressions) Await expressions - - [§12.9.8.1](expressions.md#12981-general) General - - [§12.9.8.2](expressions.md#12982-awaitable-expressions) Awaitable expressions - - [§12.9.8.3](expressions.md#12983-classification-of-await-expressions) Classification of await expressions - - [§12.9.8.4](expressions.md#12984-run-time-evaluation-of-await-expressions) Run-time evaluation of await expressions - - [§12.10](expressions.md#1210-arithmetic-operators) Arithmetic operators - - [§12.10.1](expressions.md#12101-general) General - - [§12.10.2](expressions.md#12102-multiplication-operator) Multiplication operator - - [§12.10.3](expressions.md#12103-division-operator) Division operator - - [§12.10.4](expressions.md#12104-remainder-operator) Remainder operator - - [§12.10.5](expressions.md#12105-addition-operator) Addition operator - - [§12.10.6](expressions.md#12106-subtraction-operator) Subtraction operator - - [§12.11](expressions.md#1211-shift-operators) Shift operators - - [§12.12](expressions.md#1212-relational-and-type-testing-operators) Relational and type-testing operators - - [§12.12.1](expressions.md#12121-general) General - - [§12.12.2](expressions.md#12122-integer-comparison-operators) Integer comparison operators - - [§12.12.3](expressions.md#12123-floating-point-comparison-operators) Floating-point comparison operators - - [§12.12.4](expressions.md#12124-decimal-comparison-operators) Decimal comparison operators - - [§12.12.5](expressions.md#12125-boolean-equality-operators) Boolean equality operators - - [§12.12.6](expressions.md#12126-enumeration-comparison-operators) Enumeration comparison operators - - [§12.12.7](expressions.md#12127-reference-type-equality-operators) Reference type equality operators - - [§12.12.8](expressions.md#12128-string-equality-operators) String equality operators - - [§12.12.9](expressions.md#12129-delegate-equality-operators) Delegate equality operators - - [§12.12.10](expressions.md#121210-equality-operators-between-nullable-value-types-and-the-null-literal) Equality operators between nullable value types and the null literal - - [§12.12.11](expressions.md#121211-tuple-equality-operators) Tuple equality operators - - [§12.12.12](expressions.md#121212-the-is-operator) The is operator - - [§12.12.12.1](expressions.md#1212121-the-is-type-operator) The is-type operator - - [§12.12.12.2](expressions.md#1212122-the-is-pattern-operator) The is-pattern operator - - [§12.12.13](expressions.md#121213-the-as-operator) The as operator - - [§12.13](expressions.md#1213-logical-operators) Logical operators + - [§12.9.6](expressions.md#1296-hat-operator) Hat operator + - [§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators) Prefix increment and decrement operators + - [§12.9.8](expressions.md#1298-cast-expressions) Cast expressions + - [§12.9.9](expressions.md#1299-await-expressions) Await expressions + - [§12.9.9.1](expressions.md#12991-general) General + - [§12.9.9.2](expressions.md#12992-awaitable-expressions) Awaitable expressions + - [§12.9.9.3](expressions.md#12993-classification-of-await-expressions) Classification of await expressions + - [§12.9.9.4](expressions.md#12994-run-time-evaluation-of-await-expressions) Run-time evaluation of await expressions + - [§12.10](expressions.md#1210-range-operator) Range operator + - [§12.11](expressions.md#1211-arithmetic-operators) Arithmetic operators + - [§12.11.1](expressions.md#12111-general) General + - [§12.11.2](expressions.md#12112-multiplication-operator) Multiplication operator + - [§12.11.3](expressions.md#12113-division-operator) Division operator + - [§12.11.4](expressions.md#12114-remainder-operator) Remainder operator + - [§12.11.5](expressions.md#12115-addition-operator) Addition operator + - [§12.11.6](expressions.md#12116-subtraction-operator) Subtraction operator + - [§12.12](expressions.md#1212-shift-operators) Shift operators + - [§12.13](expressions.md#1213-relational-and-type-testing-operators) Relational and type-testing operators - [§12.13.1](expressions.md#12131-general) General - - [§12.13.2](expressions.md#12132-integer-logical-operators) Integer logical operators - - [§12.13.3](expressions.md#12133-enumeration-logical-operators) Enumeration logical operators - - [§12.13.4](expressions.md#12134-boolean-logical-operators) Boolean logical operators - - [§12.13.5](expressions.md#12135-nullable-boolean--and--operators) Nullable Boolean & and | operators - - [§12.14](expressions.md#1214-conditional-logical-operators) Conditional logical operators + - [§12.13.2](expressions.md#12132-integer-comparison-operators) Integer comparison operators + - [§12.13.3](expressions.md#12133-floating-point-comparison-operators) Floating-point comparison operators + - [§12.13.4](expressions.md#12134-decimal-comparison-operators) Decimal comparison operators + - [§12.13.5](expressions.md#12135-boolean-equality-operators) Boolean equality operators + - [§12.13.6](expressions.md#12136-enumeration-comparison-operators) Enumeration comparison operators + - [§12.13.7](expressions.md#12137-reference-type-equality-operators) Reference type equality operators + - [§12.13.8](expressions.md#12138-string-equality-operators) String equality operators + - [§12.13.9](expressions.md#12139-delegate-equality-operators) Delegate equality operators + - [§12.13.10](expressions.md#121310-equality-operators-between-nullable-value-types-and-the-null-literal) Equality operators between nullable value types and the null literal + - [§12.13.11](expressions.md#121311-tuple-equality-operators) Tuple equality operators + - [§12.13.12](expressions.md#121312-the-is-operator) The is operator + - [§12.13.12.1](expressions.md#1213121-the-is-type-operator) The is-type operator + - [§12.13.12.2](expressions.md#1213122-the-is-pattern-operator) The is-pattern operator + - [§12.13.13](expressions.md#121313-the-as-operator) The as operator + - [§12.14](expressions.md#1214-logical-operators) Logical operators - [§12.14.1](expressions.md#12141-general) General - - [§12.14.2](expressions.md#12142-boolean-conditional-logical-operators) Boolean conditional logical operators - - [§12.14.3](expressions.md#12143-user-defined-conditional-logical-operators) User-defined conditional logical operators - - [§12.15](expressions.md#1215-the-null-coalescing-operator) The null coalescing operator - - [§12.16](expressions.md#1216-the-throw-expression-operator) The throw expression operator - - [§12.17](expressions.md#1217-declaration-expressions) Declaration expressions - - [§12.18](expressions.md#1218-conditional-operator) Conditional operator - - [§12.19](expressions.md#1219-anonymous-function-expressions) Anonymous function expressions - - [§12.19.1](expressions.md#12191-general) General - - [§12.19.2](expressions.md#12192-anonymous-function-signatures) Anonymous function signatures - - [§12.19.3](expressions.md#12193-anonymous-function-bodies) Anonymous function bodies - - [§12.19.4](expressions.md#12194-overload-resolution) Overload resolution - - [§12.19.5](expressions.md#12195-anonymous-functions-and-dynamic-binding) Anonymous functions and dynamic binding - - [§12.19.6](expressions.md#12196-outer-variables) Outer variables - - [§12.19.6.1](expressions.md#121961-general) General - - [§12.19.6.2](expressions.md#121962-captured-outer-variables) Captured outer variables - - [§12.19.6.3](expressions.md#121963-instantiation-of-local-variables) Instantiation of local variables - - [§12.19.7](expressions.md#12197-evaluation-of-anonymous-function-expressions) Evaluation of anonymous function expressions - - [§12.19.8](expressions.md#12198-implementation-example) Implementation Example - - [§12.20](expressions.md#1220-query-expressions) Query expressions + - [§12.14.2](expressions.md#12142-integer-logical-operators) Integer logical operators + - [§12.14.3](expressions.md#12143-enumeration-logical-operators) Enumeration logical operators + - [§12.14.4](expressions.md#12144-boolean-logical-operators) Boolean logical operators + - [§12.14.5](expressions.md#12145-nullable-boolean--and--operators) Nullable Boolean & and | operators + - [§12.15](expressions.md#1215-conditional-logical-operators) Conditional logical operators + - [§12.15.1](expressions.md#12151-general) General + - [§12.15.2](expressions.md#12152-boolean-conditional-logical-operators) Boolean conditional logical operators + - [§12.15.3](expressions.md#12153-user-defined-conditional-logical-operators) User-defined conditional logical operators + - [§12.16](expressions.md#1216-the-null-coalescing-operator) The null coalescing operator + - [§12.17](expressions.md#1217-the-throw-expression-operator) The throw expression operator + - [§12.18](expressions.md#1218-declaration-expressions) Declaration expressions + - [§12.19](expressions.md#1219-conditional-operator) Conditional operator + - [§12.20](expressions.md#1220-anonymous-function-expressions) Anonymous function expressions - [§12.20.1](expressions.md#12201-general) General - - [§12.20.2](expressions.md#12202-ambiguities-in-query-expressions) Ambiguities in query expressions - - [§12.20.3](expressions.md#12203-query-expression-translation) Query expression translation - - [§12.20.3.1](expressions.md#122031-general) General - - [§12.20.3.2](expressions.md#122032-query-expressions-with-continuations) Query expressions with continuations - - [§12.20.3.3](expressions.md#122033-explicit-range-variable-types) Explicit range variable types - - [§12.20.3.4](expressions.md#122034-degenerate-query-expressions) Degenerate query expressions - - [§12.20.3.5](expressions.md#122035-from-let-where-join-and-orderby-clauses) From, let, where, join and orderby clauses - - [§12.20.3.6](expressions.md#122036-select-clauses) Select clauses - - [§12.20.3.7](expressions.md#122037-group-clauses) Group clauses - - [§12.20.3.8](expressions.md#122038-transparent-identifiers) Transparent identifiers - - [§12.20.4](expressions.md#12204-the-query-expression-pattern) The query-expression pattern - - [§12.21](expressions.md#1221-assignment-operators) Assignment operators + - [§12.20.2](expressions.md#12202-anonymous-function-signatures) Anonymous function signatures + - [§12.20.3](expressions.md#12203-anonymous-function-bodies) Anonymous function bodies + - [§12.20.4](expressions.md#12204-overload-resolution) Overload resolution + - [§12.20.5](expressions.md#12205-anonymous-functions-and-dynamic-binding) Anonymous functions and dynamic binding + - [§12.20.6](expressions.md#12206-outer-variables) Outer variables + - [§12.20.6.1](expressions.md#122061-general) General + - [§12.20.6.2](expressions.md#122062-captured-outer-variables) Captured outer variables + - [§12.20.6.3](expressions.md#122063-instantiation-of-local-variables) Instantiation of local variables + - [§12.20.7](expressions.md#12207-evaluation-of-anonymous-function-expressions) Evaluation of anonymous function expressions + - [§12.20.8](expressions.md#12208-implementation-example) Implementation Example + - [§12.21](expressions.md#1221-query-expressions) Query expressions - [§12.21.1](expressions.md#12211-general) General - - [§12.21.2](expressions.md#12212-simple-assignment) Simple assignment - - [§12.21.3](expressions.md#12213-ref-assignment) Ref assignment - - [§12.21.4](expressions.md#12214-compound-assignment) Compound assignment - - [§12.21.5](expressions.md#12215-event-assignment) Event assignment - - [§12.22](expressions.md#1222-expression) Expression - - [§12.23](expressions.md#1223-constant-expressions) Constant expressions - - [§12.24](expressions.md#1224-boolean-expressions) Boolean expressions + - [§12.21.2](expressions.md#12212-ambiguities-in-query-expressions) Ambiguities in query expressions + - [§12.21.3](expressions.md#12213-query-expression-translation) Query expression translation + - [§12.21.3.1](expressions.md#122131-general) General + - [§12.21.3.2](expressions.md#122132-query-expressions-with-continuations) Query expressions with continuations + - [§12.21.3.3](expressions.md#122133-explicit-range-variable-types) Explicit range variable types + - [§12.21.3.4](expressions.md#122134-degenerate-query-expressions) Degenerate query expressions + - [§12.21.3.5](expressions.md#122135-from-let-where-join-and-orderby-clauses) From, let, where, join and orderby clauses + - [§12.21.3.6](expressions.md#122136-select-clauses) Select clauses + - [§12.21.3.7](expressions.md#122137-group-clauses) Group clauses + - [§12.21.3.8](expressions.md#122138-transparent-identifiers) Transparent identifiers + - [§12.21.4](expressions.md#12214-the-query-expression-pattern) The query-expression pattern + - [§12.22](expressions.md#1222-assignment-operators) Assignment operators + - [§12.22.1](expressions.md#12221-general) General + - [§12.22.2](expressions.md#12222-simple-assignment) Simple assignment + - [§12.22.3](expressions.md#12223-ref-assignment) Ref assignment + - [§12.22.4](expressions.md#12224-compound-assignment) Compound assignment + - [§12.22.5](expressions.md#12225-event-assignment) Event assignment + - [§12.23](expressions.md#1223-expression) Expression + - [§12.24](expressions.md#1224-constant-expressions) Constant expressions + - [§12.25](expressions.md#1225-boolean-expressions) Boolean expressions - [§13](statements.md#13-statements) Statements - [§13.1](statements.md#131-general) General - [§13.2](statements.md#132-end-points-and-reachability) End points and reachability @@ -675,121 +678,125 @@ - [§17.5](arrays.md#175-array-members) Array members - [§17.6](arrays.md#176-array-covariance) Array covariance - [§17.7](arrays.md#177-array-initializers) Array initializers -- [§18](interfaces.md#18-interfaces) Interfaces - - [§18.1](interfaces.md#181-general) General - - [§18.2](interfaces.md#182-interface-declarations) Interface declarations - - [§18.2.1](interfaces.md#1821-general) General - - [§18.2.2](interfaces.md#1822-interface-modifiers) Interface modifiers - - [§18.2.3](interfaces.md#1823-variant-type-parameter-lists) Variant type parameter lists - - [§18.2.3.1](interfaces.md#18231-general) General - - [§18.2.3.2](interfaces.md#18232-variance-safety) Variance safety - - [§18.2.3.3](interfaces.md#18233-variance-conversion) Variance conversion - - [§18.2.4](interfaces.md#1824-base-interfaces) Base interfaces - - [§18.3](interfaces.md#183-interface-body) Interface body - - [§18.4](interfaces.md#184-interface-members) Interface members - - [§18.4.1](interfaces.md#1841-general) General - - [§18.4.2](interfaces.md#1842-interface-methods) Interface methods - - [§18.4.3](interfaces.md#1843-interface-properties) Interface properties - - [§18.4.4](interfaces.md#1844-interface-events) Interface events - - [§18.4.5](interfaces.md#1845-interface-indexers) Interface indexers - - [§18.4.6](interfaces.md#1846-interface-member-access) Interface member access - - [§18.5](interfaces.md#185-qualified-interface-member-names) Qualified interface member names - - [§18.6](interfaces.md#186-interface-implementations) Interface implementations - - [§18.6.1](interfaces.md#1861-general) General - - [§18.6.2](interfaces.md#1862-explicit-interface-member-implementations) Explicit interface member implementations - - [§18.6.3](interfaces.md#1863-uniqueness-of-implemented-interfaces) Uniqueness of implemented interfaces - - [§18.6.4](interfaces.md#1864-implementation-of-generic-methods) Implementation of generic methods - - [§18.6.5](interfaces.md#1865-interface-mapping) Interface mapping - - [§18.6.6](interfaces.md#1866-interface-implementation-inheritance) Interface implementation inheritance - - [§18.6.7](interfaces.md#1867-interface-re-implementation) Interface re-implementation - - [§18.6.8](interfaces.md#1868-abstract-classes-and-interfaces) Abstract classes and interfaces -- [§19](enums.md#19-enums) Enums - - [§19.1](enums.md#191-general) General - - [§19.2](enums.md#192-enum-declarations) Enum declarations - - [§19.3](enums.md#193-enum-modifiers) Enum modifiers - - [§19.4](enums.md#194-enum-members) Enum members - - [§19.5](enums.md#195-the-systemenum-type) The System.Enum type - - [§19.6](enums.md#196-enum-values-and-operations) Enum values and operations -- [§20](delegates.md#20-delegates) Delegates - - [§20.1](delegates.md#201-general) General - - [§20.2](delegates.md#202-delegate-declarations) Delegate declarations - - [§20.3](delegates.md#203-delegate-members) Delegate members - - [§20.4](delegates.md#204-delegate-compatibility) Delegate compatibility - - [§20.5](delegates.md#205-delegate-instantiation) Delegate instantiation - - [§20.6](delegates.md#206-delegate-invocation) Delegate invocation -- [§21](exceptions.md#21-exceptions) Exceptions - - [§21.1](exceptions.md#211-general) General - - [§21.2](exceptions.md#212-causes-of-exceptions) Causes of exceptions - - [§21.3](exceptions.md#213-the-systemexception-class) The System.Exception class - - [§21.4](exceptions.md#214-how-exceptions-are-handled) How exceptions are handled - - [§21.5](exceptions.md#215-common-exception-classes) Common exception classes -- [§22](attributes.md#22-attributes) Attributes - - [§22.1](attributes.md#221-general) General - - [§22.2](attributes.md#222-attribute-classes) Attribute classes - - [§22.2.1](attributes.md#2221-general) General - - [§22.2.2](attributes.md#2222-attribute-usage) Attribute usage - - [§22.2.3](attributes.md#2223-positional-and-named-parameters) Positional and named parameters - - [§22.2.4](attributes.md#2224-attribute-parameter-types) Attribute parameter types - - [§22.3](attributes.md#223-attribute-specification) Attribute specification - - [§22.4](attributes.md#224-attribute-instances) Attribute instances - - [§22.4.1](attributes.md#2241-general) General - - [§22.4.2](attributes.md#2242-compilation-of-an-attribute) Compilation of an attribute - - [§22.4.3](attributes.md#2243-run-time-retrieval-of-an-attribute-instance) Run-time retrieval of an attribute instance - - [§22.5](attributes.md#225-reserved-attributes) Reserved attributes - - [§22.5.1](attributes.md#2251-general) General - - [§22.5.2](attributes.md#2252-the-attributeusage-attribute) The AttributeUsage attribute - - [§22.5.3](attributes.md#2253-the-conditional-attribute) The Conditional attribute - - [§22.5.3.1](attributes.md#22531-general) General - - [§22.5.3.2](attributes.md#22532-conditional-methods) Conditional methods - - [§22.5.3.3](attributes.md#22533-conditional-attribute-classes) Conditional attribute classes - - [§22.5.4](attributes.md#2254-the-obsolete-attribute) The Obsolete attribute - - [§22.5.5](attributes.md#2255-the-asyncmethodbuilder-attribute) The AsyncMethodBuilder attribute - - [§22.5.6](attributes.md#2256-caller-info-attributes) Caller-info attributes - - [§22.5.6.1](attributes.md#22561-general) General - - [§22.5.6.2](attributes.md#22562-the-callerlinenumber-attribute) The CallerLineNumber attribute - - [§22.5.6.3](attributes.md#22563-the-callerfilepath-attribute) The CallerFilePath attribute - - [§22.5.6.4](attributes.md#22564-the-callermembername-attribute) The CallerMemberName attribute - - [§22.5.7](attributes.md#2257-code-analysis-attributes) Code analysis attributes - - [§22.5.7.1](attributes.md#22571-general) General - - [§22.5.7.2](attributes.md#22572-the-allownull-attribute) The AllowNull attribute - - [§22.5.7.3](attributes.md#22573-the-disallownull-attribute) The DisallowNull attribute - - [§22.5.7.4](attributes.md#22574-the-doesnotreturn-attribute) The DoesNotReturn attribute - - [§22.5.7.5](attributes.md#22575-the-doesnotreturnif-attribute) The DoesNotReturnIf attribute - - [§22.5.7.6](attributes.md#22576-the-maybenull-attribute) The MaybeNull attribute - - [§22.5.7.7](attributes.md#22577-the-maybenullwhen-attribute) The MaybeNullWhen attribute - - [§22.5.7.8](attributes.md#22578-the-notnull-attribute) The NotNull attribute - - [§22.5.7.9](attributes.md#22579-the-notnullifnotnull-attribute) The NotNullIfNotNull attribute - - [§22.5.7.10](attributes.md#225710-the-notnullwhen-attribute) The NotNullWhen attribute - - [§22.6](attributes.md#226-attributes-for-interoperation) Attributes for interoperation -- [§23](unsafe-code.md#23-unsafe-code) Unsafe code - - [§23.1](unsafe-code.md#231-general) General - - [§23.2](unsafe-code.md#232-unsafe-contexts) Unsafe contexts - - [§23.3](unsafe-code.md#233-pointer-types) Pointer types - - [§23.4](unsafe-code.md#234-fixed-and-moveable-variables) Fixed and moveable variables - - [§23.5](unsafe-code.md#235-pointer-conversions) Pointer conversions - - [§23.5.1](unsafe-code.md#2351-general) General - - [§23.5.2](unsafe-code.md#2352-pointer-arrays) Pointer arrays - - [§23.6](unsafe-code.md#236-pointers-in-expressions) Pointers in expressions - - [§23.6.1](unsafe-code.md#2361-general) General - - [§23.6.2](unsafe-code.md#2362-pointer-indirection) Pointer indirection - - [§23.6.3](unsafe-code.md#2363-pointer-member-access) Pointer member access - - [§23.6.4](unsafe-code.md#2364-pointer-element-access) Pointer element access - - [§23.6.5](unsafe-code.md#2365-the-address-of-operator) The address-of operator - - [§23.6.6](unsafe-code.md#2366-pointer-increment-and-decrement) Pointer increment and decrement - - [§23.6.7](unsafe-code.md#2367-pointer-arithmetic) Pointer arithmetic - - [§23.6.8](unsafe-code.md#2368-pointer-comparison) Pointer comparison - - [§23.6.9](unsafe-code.md#2369-the-sizeof-operator) The sizeof operator - - [§23.7](unsafe-code.md#237-the-fixed-statement) The fixed statement - - [§23.8](unsafe-code.md#238-fixed-size-buffers) Fixed-size buffers - - [§23.8.1](unsafe-code.md#2381-general) General - - [§23.8.2](unsafe-code.md#2382-fixed-size-buffer-declarations) Fixed-size buffer declarations - - [§23.8.3](unsafe-code.md#2383-fixed-size-buffers-in-expressions) Fixed-size buffers in expressions - - [§23.8.4](unsafe-code.md#2384-definite-assignment-checking) Definite assignment checking - - [§23.9](unsafe-code.md#239-stack-allocation) Stack allocation -- [§24](ranges.md#24-ranges-and-slicing) Ranges and Slicing - - [§24.1](ranges.md#241-general) General - - [§24.2](ranges.md#242-the-index-type) The Index type - - [§24.3](ranges.md#243-the-range-type) The Range type +- [§18](ranges.md#18-extended-indexing-and-slicing) Extended indexing and slicing + - [§18.1](ranges.md#181-general) General + - [§18.2](ranges.md#182-the-index-type) The Index type + - [§18.3](ranges.md#183-the-range-type) The Range type + - [§18.4](ranges.md#184-pattern-based-implicit-support-for-index-and-range) Pattern-based implicit support for Index and Range + - [§18.4.1](ranges.md#1841-general) General + - [§18.4.2](ranges.md#1842-implicit-index-support) Implicit Index support + - [§18.4.3](ranges.md#1843-implicit-range-support) Implicit Range support +- [§19](interfaces.md#19-interfaces) Interfaces + - [§19.1](interfaces.md#191-general) General + - [§19.2](interfaces.md#192-interface-declarations) Interface declarations + - [§19.2.1](interfaces.md#1921-general) General + - [§19.2.2](interfaces.md#1922-interface-modifiers) Interface modifiers + - [§19.2.3](interfaces.md#1923-variant-type-parameter-lists) Variant type parameter lists + - [§19.2.3.1](interfaces.md#19231-general) General + - [§19.2.3.2](interfaces.md#19232-variance-safety) Variance safety + - [§19.2.3.3](interfaces.md#19233-variance-conversion) Variance conversion + - [§19.2.4](interfaces.md#1924-base-interfaces) Base interfaces + - [§19.3](interfaces.md#193-interface-body) Interface body + - [§19.4](interfaces.md#194-interface-members) Interface members + - [§19.4.1](interfaces.md#1941-general) General + - [§19.4.2](interfaces.md#1942-interface-methods) Interface methods + - [§19.4.3](interfaces.md#1943-interface-properties) Interface properties + - [§19.4.4](interfaces.md#1944-interface-events) Interface events + - [§19.4.5](interfaces.md#1945-interface-indexers) Interface indexers + - [§19.4.6](interfaces.md#1946-interface-member-access) Interface member access + - [§19.5](interfaces.md#195-qualified-interface-member-names) Qualified interface member names + - [§19.6](interfaces.md#196-interface-implementations) Interface implementations + - [§19.6.1](interfaces.md#1961-general) General + - [§19.6.2](interfaces.md#1962-explicit-interface-member-implementations) Explicit interface member implementations + - [§19.6.3](interfaces.md#1963-uniqueness-of-implemented-interfaces) Uniqueness of implemented interfaces + - [§19.6.4](interfaces.md#1964-implementation-of-generic-methods) Implementation of generic methods + - [§19.6.5](interfaces.md#1965-interface-mapping) Interface mapping + - [§19.6.6](interfaces.md#1966-interface-implementation-inheritance) Interface implementation inheritance + - [§19.6.7](interfaces.md#1967-interface-re-implementation) Interface re-implementation + - [§19.6.8](interfaces.md#1968-abstract-classes-and-interfaces) Abstract classes and interfaces +- [§20](enums.md#20-enums) Enums + - [§20.1](enums.md#201-general) General + - [§20.2](enums.md#202-enum-declarations) Enum declarations + - [§20.3](enums.md#203-enum-modifiers) Enum modifiers + - [§20.4](enums.md#204-enum-members) Enum members + - [§20.5](enums.md#205-the-systemenum-type) The System.Enum type + - [§20.6](enums.md#206-enum-values-and-operations) Enum values and operations +- [§21](delegates.md#21-delegates) Delegates + - [§21.1](delegates.md#211-general) General + - [§21.2](delegates.md#212-delegate-declarations) Delegate declarations + - [§21.3](delegates.md#213-delegate-members) Delegate members + - [§21.4](delegates.md#214-delegate-compatibility) Delegate compatibility + - [§21.5](delegates.md#215-delegate-instantiation) Delegate instantiation + - [§21.6](delegates.md#216-delegate-invocation) Delegate invocation +- [§22](exceptions.md#22-exceptions) Exceptions + - [§22.1](exceptions.md#221-general) General + - [§22.2](exceptions.md#222-causes-of-exceptions) Causes of exceptions + - [§22.3](exceptions.md#223-the-systemexception-class) The System.Exception class + - [§22.4](exceptions.md#224-how-exceptions-are-handled) How exceptions are handled + - [§22.5](exceptions.md#225-common-exception-classes) Common exception classes +- [§23](attributes.md#23-attributes) Attributes + - [§23.1](attributes.md#231-general) General + - [§23.2](attributes.md#232-attribute-classes) Attribute classes + - [§23.2.1](attributes.md#2321-general) General + - [§23.2.2](attributes.md#2322-attribute-usage) Attribute usage + - [§23.2.3](attributes.md#2323-positional-and-named-parameters) Positional and named parameters + - [§23.2.4](attributes.md#2324-attribute-parameter-types) Attribute parameter types + - [§23.3](attributes.md#233-attribute-specification) Attribute specification + - [§23.4](attributes.md#234-attribute-instances) Attribute instances + - [§23.4.1](attributes.md#2341-general) General + - [§23.4.2](attributes.md#2342-compilation-of-an-attribute) Compilation of an attribute + - [§23.4.3](attributes.md#2343-run-time-retrieval-of-an-attribute-instance) Run-time retrieval of an attribute instance + - [§23.5](attributes.md#235-reserved-attributes) Reserved attributes + - [§23.5.1](attributes.md#2351-general) General + - [§23.5.2](attributes.md#2352-the-attributeusage-attribute) The AttributeUsage attribute + - [§23.5.3](attributes.md#2353-the-conditional-attribute) The Conditional attribute + - [§23.5.3.1](attributes.md#23531-general) General + - [§23.5.3.2](attributes.md#23532-conditional-methods) Conditional methods + - [§23.5.3.3](attributes.md#23533-conditional-attribute-classes) Conditional attribute classes + - [§23.5.4](attributes.md#2354-the-obsolete-attribute) The Obsolete attribute + - [§23.5.5](attributes.md#2355-the-asyncmethodbuilder-attribute) The AsyncMethodBuilder attribute + - [§23.5.6](attributes.md#2356-caller-info-attributes) Caller-info attributes + - [§23.5.6.1](attributes.md#23561-general) General + - [§23.5.6.2](attributes.md#23562-the-callerlinenumber-attribute) The CallerLineNumber attribute + - [§23.5.6.3](attributes.md#23563-the-callerfilepath-attribute) The CallerFilePath attribute + - [§23.5.6.4](attributes.md#23564-the-callermembername-attribute) The CallerMemberName attribute + - [§23.5.7](attributes.md#2357-code-analysis-attributes) Code analysis attributes + - [§23.5.7.1](attributes.md#23571-general) General + - [§23.5.7.2](attributes.md#23572-the-allownull-attribute) The AllowNull attribute + - [§23.5.7.3](attributes.md#23573-the-disallownull-attribute) The DisallowNull attribute + - [§23.5.7.4](attributes.md#23574-the-doesnotreturn-attribute) The DoesNotReturn attribute + - [§23.5.7.5](attributes.md#23575-the-doesnotreturnif-attribute) The DoesNotReturnIf attribute + - [§23.5.7.6](attributes.md#23576-the-maybenull-attribute) The MaybeNull attribute + - [§23.5.7.7](attributes.md#23577-the-maybenullwhen-attribute) The MaybeNullWhen attribute + - [§23.5.7.8](attributes.md#23578-the-notnull-attribute) The NotNull attribute + - [§23.5.7.9](attributes.md#23579-the-notnullifnotnull-attribute) The NotNullIfNotNull attribute + - [§23.5.7.10](attributes.md#235710-the-notnullwhen-attribute) The NotNullWhen attribute + - [§23.6](attributes.md#236-attributes-for-interoperation) Attributes for interoperation +- [§24](unsafe-code.md#24-unsafe-code) Unsafe code + - [§24.1](unsafe-code.md#241-general) General + - [§24.2](unsafe-code.md#242-unsafe-contexts) Unsafe contexts + - [§24.3](unsafe-code.md#243-pointer-types) Pointer types + - [§24.4](unsafe-code.md#244-fixed-and-moveable-variables) Fixed and moveable variables + - [§24.5](unsafe-code.md#245-pointer-conversions) Pointer conversions + - [§24.5.1](unsafe-code.md#2451-general) General + - [§24.5.2](unsafe-code.md#2452-pointer-arrays) Pointer arrays + - [§24.6](unsafe-code.md#246-pointers-in-expressions) Pointers in expressions + - [§24.6.1](unsafe-code.md#2461-general) General + - [§24.6.2](unsafe-code.md#2462-pointer-indirection) Pointer indirection + - [§24.6.3](unsafe-code.md#2463-pointer-member-access) Pointer member access + - [§24.6.4](unsafe-code.md#2464-pointer-element-access) Pointer element access + - [§24.6.5](unsafe-code.md#2465-the-address-of-operator) The address-of operator + - [§24.6.6](unsafe-code.md#2466-pointer-increment-and-decrement) Pointer increment and decrement + - [§24.6.7](unsafe-code.md#2467-pointer-arithmetic) Pointer arithmetic + - [§24.6.8](unsafe-code.md#2468-pointer-comparison) Pointer comparison + - [§24.6.9](unsafe-code.md#2469-the-sizeof-operator) The sizeof operator + - [§24.7](unsafe-code.md#247-the-fixed-statement) The fixed statement + - [§24.8](unsafe-code.md#248-fixed-size-buffers) Fixed-size buffers + - [§24.8.1](unsafe-code.md#2481-general) General + - [§24.8.2](unsafe-code.md#2482-fixed-size-buffer-declarations) Fixed-size buffer declarations + - [§24.8.3](unsafe-code.md#2483-fixed-size-buffers-in-expressions) Fixed-size buffers in expressions + - [§24.8.4](unsafe-code.md#2484-definite-assignment-checking) Definite assignment checking + - [§24.9](unsafe-code.md#249-stack-allocation) Stack allocation - [§A](grammar.md#annex-a-grammar) Grammar - [§A.1](grammar.md#a1-general) General - [§A.2](grammar.md#a2-lexical-grammar) Lexical grammar diff --git a/standard/arrays.md b/standard/arrays.md index a3d60ea23..024417569 100644 --- a/standard/arrays.md +++ b/standard/arrays.md @@ -112,7 +112,7 @@ Elements of arrays created by *array_creation_expression*s are always initialize ## 17.4 Array element access -Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference (§9.5) to the array element selected by the indices. +Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference ([§9.5](variables.md#95-variable-references)) to the array element selected by the indices. Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to that type, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to that type, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range`, maintaining the element order. @@ -126,7 +126,7 @@ Every array type inherits the members declared by the `System.Array` type. For any two *reference_type*s `A` and `B`, if an implicit reference conversion ([§10.2.8](conversions.md#1028-implicit-reference-conversions)) or explicit reference conversion ([§10.3.5](conversions.md#1035-explicit-reference-conversions)) exists from `A` to `B`, then the same reference conversion also exists from the array type `A[R]` to the array type `B[R]`, where `R` is any given *rank_specifier* (but the same for both array types). This relationship is known as ***array covariance***. Array covariance, in particular, means that a value of an array type `A[R]` might actually be a reference to an instance of an array type `B[R]`, provided an implicit reference conversion exists from `B` to `A`. -Because of array covariance, assignments to elements of reference type arrays include a run-time check which ensures that the value being assigned to the array element is actually of a permitted type ([§12.21.2](expressions.md#12212-simple-assignment)). +Because of array covariance, assignments to elements of reference type arrays include a run-time check which ensures that the value being assigned to the array element is actually of a permitted type ([§12.22.2](expressions.md#12222-simple-assignment)). > *Example*: > diff --git a/standard/attributes.md b/standard/attributes.md index d5de3cf43..eb325d23f 100644 --- a/standard/attributes.md +++ b/standard/attributes.md @@ -1,6 +1,6 @@ -# 22 Attributes +# 23 Attributes -## 22.1 General +## 23.1 General Much of the C# language enables the programmer to specify declarative information about the entities defined in the program. For example, the accessibility of a method in a class is specified by decorating it with the *method_modifier*s `public`, `protected`, `internal`, and `private`. @@ -8,11 +8,11 @@ C# enables programmers to invent new kinds of declarative information, called ** > *Note*: For instance, a framework might define a `HelpAttribute` attribute that can be placed on certain program elements (such as classes and methods) to provide a mapping from those program elements to their documentation. *end note* -Attributes are defined through the declaration of attribute classes ([§22.2](attributes.md#222-attribute-classes)), which can have positional and named parameters ([§22.2.3](attributes.md#2223-positional-and-named-parameters)). Attributes are attached to entities in a C# program using attribute specifications ([§22.3](attributes.md#223-attribute-specification)), and can be retrieved at run-time as attribute instances ([§22.4](attributes.md#224-attribute-instances)). +Attributes are defined through the declaration of attribute classes ([§23.2](attributes.md#232-attribute-classes)), which can have positional and named parameters ([§23.2.3](attributes.md#2323-positional-and-named-parameters)). Attributes are attached to entities in a C# program using attribute specifications ([§23.3](attributes.md#233-attribute-specification)), and can be retrieved at run-time as attribute instances ([§23.4](attributes.md#234-attribute-instances)). -## 22.2 Attribute classes +## 23.2 Attribute classes -### 22.2.1 General +### 23.2.1 General A class that derives from the abstract class `System.Attribute`, whether directly or indirectly, is an ***attribute class***. The declaration of an attribute class defines a new kind of attribute that can be placed on program entities. By convention, attribute classes are named with a suffix of `Attribute`. Uses of an attribute may either include or omit this suffix. @@ -28,11 +28,11 @@ A generic class declaration shall not use `System.Attribute` as a direct or indi > > *end example* -### 22.2.2 Attribute usage +### 23.2.2 Attribute usage -The attribute `AttributeUsage` ([§22.5.2](attributes.md#2252-the-attributeusage-attribute)) is used to describe how an attribute class can be used. +The attribute `AttributeUsage` ([§23.5.2](attributes.md#2352-the-attributeusage-attribute)) is used to describe how an attribute class can be used. -`AttributeUsage` has a positional parameter ([§22.2.3](attributes.md#2223-positional-and-named-parameters)) that enables an attribute class to specify the kinds of program entities on which it can be used. +`AttributeUsage` has a positional parameter ([§23.2.3](attributes.md#2323-positional-and-named-parameters)) that enables an attribute class to specify the kinds of program entities on which it can be used. > *Example*: The following example defines an attribute class named `SimpleAttribute` that can be placed on *class_declaration*s and *interface_declaration*s only, and shows several uses of the `Simple` attribute. > @@ -59,7 +59,7 @@ The attribute `AttributeUsage` ([§22.5.2](attributes.md#2252-the-attributeusage > > *end example* -`AttributeUsage` has a named parameter ([§22.2.3](attributes.md#2223-positional-and-named-parameters)), called `AllowMultiple`, which indicates whether the attribute can be specified more than once for a given entity. If `AllowMultiple` for an attribute class is true, then that attribute class is a ***multi-use attribute class***, and can be specified more than once on an entity. If `AllowMultiple` for an attribute class is false or it is unspecified, then that attribute class is a ***single-use attribute class***, and can be specified at most once on an entity. +`AttributeUsage` has a named parameter ([§23.2.3](attributes.md#2323-positional-and-named-parameters)), called `AllowMultiple`, which indicates whether the attribute can be specified more than once for a given entity. If `AllowMultiple` for an attribute class is true, then that attribute class is a ***multi-use attribute class***, and can be specified more than once on an entity. If `AllowMultiple` for an attribute class is false or it is unspecified, then that attribute class is a ***single-use attribute class***, and can be specified at most once on an entity. > *Example*: The following example defines a multi-use attribute class named `AuthorAttribute` and shows a class declaration with two uses of the `Author` attribute: > @@ -82,7 +82,7 @@ The attribute `AttributeUsage` ([§22.5.2](attributes.md#2252-the-attributeusage > > *end example* -`AttributeUsage` has another named parameter ([§22.2.3](attributes.md#2223-positional-and-named-parameters)), called `Inherited`, which indicates whether the attribute, when specified on a base class, is also inherited by classes that derive from that base class. If `Inherited` for an attribute class is true, then that attribute is inherited. If `Inherited` for an attribute class is false then that attribute is not inherited. If it is unspecified, its default value is true. +`AttributeUsage` has another named parameter ([§23.2.3](attributes.md#2323-positional-and-named-parameters)), called `Inherited`, which indicates whether the attribute, when specified on a base class, is also inherited by classes that derive from that base class. If `Inherited` for an attribute class is true, then that attribute is inherited. If `Inherited` for an attribute class is false then that attribute is not inherited. If it is unspecified, its default value is true. An attribute class `X` not having an `AttributeUsage` attribute attached to it, as in @@ -103,7 +103,7 @@ is equivalent to the following: class X : Attribute { ... } ``` -### 22.2.3 Positional and named parameters +### 23.2.3 Positional and named parameters Attribute classes can have ***positional parameter***s and ***named parameter***s. Each public instance constructor for an attribute class defines a valid sequence of positional parameters for that attribute class. Each non-static public read-write field and property for an attribute class defines a named parameter for the attribute class. For a property to define a named parameter, that property shall have both a public get accessor and a public set accessor. @@ -143,7 +143,7 @@ Attribute classes can have ***positional parameter***s and ***named parameter*** > > *end example* -### 22.2.4 Attribute parameter types +### 23.2.4 Attribute parameter types The types of positional and named parameters for an attribute class are limited to the ***attribute parameter types***, which are: @@ -154,9 +154,9 @@ The types of positional and named parameters for an attribute class are limited - Single-dimensional arrays of the above types. - A constructor argument or public field that does not have one of these types, shall not be used as a positional or named parameter in an attribute specification. -## 22.3 Attribute specification +## 23.3 Attribute specification -***Attribute specification*** is the application of a previously defined attribute to a program entity. An attribute is a piece of additional declarative information that is specified for a program entity. Attributes can be specified at global scope (to specify attributes on the containing assembly or module) and for *type_declaration*s ([§14.7](namespaces.md#147-type-declarations)), *class_member_declaration*s ([§15.3](classes.md#153-class-members)), *interface_member_declaration*s ([§18.4](interfaces.md#184-interface-members)), *struct_member_declaration*s ([§16.3](structs.md#163-struct-members)), *enum_member_declaration*s ([§19.2](enums.md#192-enum-declarations)), *accessor_declaration*s ([§15.7.3](classes.md#1573-accessors)), *event_accessor_declaration*s ([§15.8](classes.md#158-events)), elements of *parameter_list*s ([§15.6.2](classes.md#1562-method-parameters)), and elements of *type_parameter_list*s ([§15.2.3](classes.md#1523-type-parameters)). +***Attribute specification*** is the application of a previously defined attribute to a program entity. An attribute is a piece of additional declarative information that is specified for a program entity. Attributes can be specified at global scope (to specify attributes on the containing assembly or module) and for *type_declaration*s ([§14.7](namespaces.md#147-type-declarations)), *class_member_declaration*s ([§15.3](classes.md#153-class-members)), *interface_member_declaration*s ([§19.4](interfaces.md#194-interface-members)), *struct_member_declaration*s ([§16.3](structs.md#163-struct-members)), *enum_member_declaration*s ([§20.2](enums.md#202-enum-declarations)), *accessor_declaration*s ([§15.7.3](classes.md#1573-accessors)), *event_accessor_declaration*s ([§15.8](classes.md#158-events)), elements of *parameter_list*s ([§15.6.2](classes.md#1562-method-parameters)), and elements of *type_parameter_list*s ([§15.2.3](classes.md#1523-type-parameters)). Attributes are specified in ***attribute sections***. An attribute section consists of a pair of square brackets, which surround a comma-separated list of one or more attributes. The order in which attributes are specified in such a list, and the order in which sections attached to the same program entity are arranged, is not significant. For instance, the attribute specifications `[A][B]`, `[B][A]`, `[A, B]`, and `[B, A]` are equivalent. @@ -384,7 +384,7 @@ It is a compile-time error to use a single-use attribute class more than once on An expression `E` is an *attribute_argument_expression* if all of the following statements are true: -- The type of `E` is an attribute parameter type ([§22.2.4](attributes.md#2224-attribute-parameter-types)). +- The type of `E` is an attribute parameter type ([§23.2.4](attributes.md#2324-attribute-parameter-types)). - At compile-time, the value of `E` can be resolved to one of the following: - A constant value. - A `System.Type` object obtained using a *typeof_expression* ([§12.8.18](expressions.md#12818-the-typeof-operator)) specifying a non-generic type, a closed constructed type ([§8.4.3](types.md#843-open-and-closed-types)), or an unbound generic type ([§8.4.4](types.md#844-bound-and-unbound-types)), but not an open type ([§8.4.3](types.md#843-open-and-closed-types)). @@ -449,15 +449,15 @@ The attributes of a type declared in multiple parts are determined by combining, Attributes on type parameters combine in the same way. -## 22.4 Attribute instances +## 23.4 Attribute instances -### 22.4.1 General +### 23.4.1 General An ***attribute instance*** is an instance that represents an attribute at run-time. An attribute is defined with an attribute class, positional arguments, and named arguments. An attribute instance is an instance of the attribute class that is initialized with the positional and named arguments. Retrieval of an attribute instance involves both compile-time and run-time processing, as described in the following subclauses. -### 22.4.2 Compilation of an attribute +### 23.4.2 Compilation of an attribute The compilation of an *attribute* with attribute class `T`, *positional_argument_list* `P`, *named_argument_list* `N`, and specified on a program entity `E` is compiled into an assembly `A` via the following steps: @@ -466,13 +466,13 @@ The compilation of an *attribute* with attribute class `T`, *positional_argumen - For each *named_argument* `Arg` in `N`: - Let `Name` be the *identifier* of the *named_argument* `Arg`. - `Name` shall identify a non-static read-write public field or property on `T`. If `T` has no such field or property, then a compile-time error occurs. -- If any of the values within *positional_argument_list* `P` or one of the values within *named_argument_list* `N` is of type `System.String` and the value is not well-formed as defined by the Unicode Standard, it is implementation-defined whether the value compiled is equal to the run-time value retrieved ([§22.4.3](attributes.md#2243-run-time-retrieval-of-an-attribute-instance)). +- If any of the values within *positional_argument_list* `P` or one of the values within *named_argument_list* `N` is of type `System.String` and the value is not well-formed as defined by the Unicode Standard, it is implementation-defined whether the value compiled is equal to the run-time value retrieved ([§23.4.3](attributes.md#2343-run-time-retrieval-of-an-attribute-instance)). > *Note*: As an example, a string which contains a high surrogate UTF-16 code unit which isn’t immediately followed by a low surrogate code unit is not well-formed. *end note* - Store the following information (for run-time instantiation of the attribute) in the assembly output by the compiler as a result of compiling the program containing the attribute: the attribute class `T`, the instance constructor `C` on `T`, the *positional_argument_list* `P`, the *named_argument_list* `N`, and the associated program entity `E`, with the values resolved completely at compile-time. -### 22.4.3 Run-time retrieval of an attribute instance +### 23.4.3 Run-time retrieval of an attribute instance -Using the terms defined in [§22.4.2](attributes.md#2242-compilation-of-an-attribute), the attribute instance represented by `T`, `C`, `P`, and `N`, and associated with `E` can be retrieved at run-time from the assembly `A` using the following steps: +Using the terms defined in [§23.4.2](attributes.md#2342-compilation-of-an-attribute), the attribute instance represented by `T`, `C`, `P`, and `N`, and associated with `E` can be retrieved at run-time from the assembly `A` using the following steps: - Follow the run-time processing steps for executing an *object_creation_expression* of the form `new T(P)`, using the instance constructor `C` and values as determined at compile-time. These steps either result in an exception, or produce an instance `O` of `T`. - For each *named_argument* `Arg` in `N`, in order: @@ -484,37 +484,37 @@ Using the terms defined in [§22.4.2](attributes.md#2242-compilation-of-an-attri > *Note*: The format for storing `T`, `C`, `P`, `N` (and associating it with `E`) in `A` and the mechanism to specify `E` and retrieve `T`, `C`, `P`, `N` from `A` (and hence how an attribute instance is obtained at runtime) is beyond the scope of this specification. *end note* -## 22.5 Reserved attributes +## 23.5 Reserved attributes -### 22.5.1 General +### 23.5.1 General A number of attributes affect the language in some way. These attributes include: -- `System.AttributeUsageAttribute` ([§22.5.2](attributes.md#2252-the-attributeusage-attribute)), which is used to describe the ways in which an attribute class can be used. -- `System.Diagnostics.ConditionalAttribute` ([§22.5.3](attributes.md#2253-the-conditional-attribute)), is a multi-use attribute class which is used to define conditional methods and conditional attribute classes. This attribute indicates a condition by testing a conditional compilation symbol. -- `System.ObsoleteAttribute` ([§22.5.4](attributes.md#2254-the-obsolete-attribute)), which is used to mark a member as obsolete. -- `System.Runtime.CompilerServices.AsyncMethodBuilderAttribute` ([§22.5.5](attributes.md#2255-the-asyncmethodbuilder-attribute)), which is used to establish a task builder for an async method. -- `System.Runtime.CompilerServices.CallerLineNumberAttribute` ([§22.5.6.2](attributes.md#22562-the-callerlinenumber-attribute)), `System.Runtime.CompilerServices.CallerFilePathAttribute` ([§22.5.6.3](attributes.md#22563-the-callerfilepath-attribute)), and `System.Runtime.CompilerServices.CallerMemberNameAttribute` ([§22.5.6.4](attributes.md#22564-the-callermembername-attribute)), which are used to supply information about the calling context to optional parameters. +- `System.AttributeUsageAttribute` ([§23.5.2](attributes.md#2352-the-attributeusage-attribute)), which is used to describe the ways in which an attribute class can be used. +- `System.Diagnostics.ConditionalAttribute` ([§23.5.3](attributes.md#2353-the-conditional-attribute)), is a multi-use attribute class which is used to define conditional methods and conditional attribute classes. This attribute indicates a condition by testing a conditional compilation symbol. +- `System.ObsoleteAttribute` ([§23.5.4](attributes.md#2354-the-obsolete-attribute)), which is used to mark a member as obsolete. +- `System.Runtime.CompilerServices.AsyncMethodBuilderAttribute` ([§23.5.5](attributes.md#2355-the-asyncmethodbuilder-attribute)), which is used to establish a task builder for an async method. +- `System.Runtime.CompilerServices.CallerLineNumberAttribute` ([§23.5.6.2](attributes.md#23562-the-callerlinenumber-attribute)), `System.Runtime.CompilerServices.CallerFilePathAttribute` ([§23.5.6.3](attributes.md#23563-the-callerfilepath-attribute)), and `System.Runtime.CompilerServices.CallerMemberNameAttribute` ([§23.5.6.4](attributes.md#23564-the-callermembername-attribute)), which are used to supply information about the calling context to optional parameters. -The Nullable static analysis attributes ([§22.5.7](attributes.md#2257-code-analysis-attributes)) can improve the correctness of warnings generated for nullabilities and null states ([§8.9.5](types.md#895-nullabilities-and-null-states)). +The Nullable static analysis attributes ([§23.5.7](attributes.md#2357-code-analysis-attributes)) can improve the correctness of warnings generated for nullabilities and null states ([§8.9.5](types.md#895-nullabilities-and-null-states)). An execution environment may provide additional implementation-defined attributes that affect the execution of a C# program. -### 22.5.2 The AttributeUsage attribute +### 23.5.2 The AttributeUsage attribute The attribute `AttributeUsage` is used to describe the manner in which the attribute class can be used. A class that is decorated with the `AttributeUsage` attribute shall derive from `System.Attribute`, either directly or indirectly. Otherwise, a compile-time error occurs. -> *Note*: For an example of using this attribute, see [§22.2.2](attributes.md#2222-attribute-usage). *end note* +> *Note*: For an example of using this attribute, see [§23.2.2](attributes.md#2322-attribute-usage). *end note* -### 22.5.3 The Conditional attribute +### 23.5.3 The Conditional attribute -#### 22.5.3.1 General +#### 23.5.3.1 General The attribute `Conditional` enables the definition of ***conditional methods*** and ***conditional attribute classes***. -#### 22.5.3.2 Conditional methods +#### 23.5.3.2 Conditional methods A method decorated with the `Conditional` attribute is a conditional method. Each conditional method is thus associated with the conditional compilation symbols declared in its `Conditional` attributes. @@ -663,9 +663,9 @@ The use of conditional methods in an inheritance chain can be confusing. Calls m > > *end example* -#### 22.5.3.3 Conditional attribute classes +#### 23.5.3.3 Conditional attribute classes -An attribute class ([§22.2](attributes.md#222-attribute-classes)) decorated with one or more `Conditional` attributes is a conditional attribute class. A conditional attribute class is thus associated with the conditional compilation symbols declared in its `Conditional` attributes. +An attribute class ([§23.2](attributes.md#232-attribute-classes)) decorated with one or more `Conditional` attributes is a conditional attribute class. A conditional attribute class is thus associated with the conditional compilation symbols declared in its `Conditional` attributes. > *Example*: > @@ -680,7 +680,7 @@ An attribute class ([§22.2](attributes.md#222-attribute-classes)) decorated wit > > *end example* -Attribute specifications ([§22.3](attributes.md#223-attribute-specification)) of a conditional attribute are included if one or more of its associated conditional compilation symbols is defined at the point of specification, otherwise the attribute specification is omitted. +Attribute specifications ([§23.3](attributes.md#233-attribute-specification)) of a conditional attribute are included if one or more of its associated conditional compilation symbols is defined at the point of specification, otherwise the attribute specification is omitted. It is important to note that the inclusion or exclusion of an attribute specification of a conditional attribute class is controlled by the conditional compilation symbols at the point of the specification. @@ -709,7 +709,7 @@ It is important to note that the inclusion or exclusion of an attribute specific > > *end example* -### 22.5.4 The Obsolete attribute +### 23.5.4 The Obsolete attribute The attribute `Obsolete` is used to mark types and members of types that should no longer be used. @@ -744,13 +744,13 @@ If a program uses a type or member that is decorated with the `Obsolete` attribu > > *end example* -### 22.5.5 The AsyncMethodBuilder attribute +### 23.5.5 The AsyncMethodBuilder attribute This attribute is described in [§15.14.1](classes.md#15141-general). -### 22.5.6 Caller-info attributes +### 23.5.6 Caller-info attributes -#### 22.5.6.1 General +#### 23.5.6.1 General For purposes such as logging and reporting, it is sometimes useful for a function member to obtain certain compile-time information about the calling code. The caller-info attributes provide a way to pass such information transparently. @@ -794,7 +794,7 @@ If more than one caller-info attribute is specified on a given parameter, they a `CallerLineNumber` takes precedence, and the other two attributes are ignored. If `CallerLineNumber` were omitted, `CallerFilePath` would take precedence, and `CallerMemberName` would be ignored. The lexical ordering of these attributes is irrelevant. -#### 22.5.6.2 The CallerLineNumber attribute +#### 23.5.6.2 The CallerLineNumber attribute The attribute `System.Runtime.CompilerServices.CallerLineNumberAttribute` is allowed on optional parameters when there is a standard implicit conversion ([§10.4.2](conversions.md#1042-standard-implicit-conversions)) from the constant value `int.MaxValue` to the parameter’s type. This ensures that any non-negative line number up to that value can be passed without error. @@ -804,7 +804,7 @@ If the invocation spans multiple lines, the line chosen is implementation-depend The line number may be affected by `#line` directives ([§6.5.8](lexical-structure.md#658-line-directives)). -#### 22.5.6.3 The CallerFilePath attribute +#### 23.5.6.3 The CallerFilePath attribute The attribute `System.Runtime.CompilerServices.CallerFilePathAttribute` is allowed on optional parameters when there is a standard implicit conversion ([§10.4.2](conversions.md#1042-standard-implicit-conversions)) from `string` to the parameter’s type. @@ -814,7 +814,7 @@ The format of the file path is implementation-dependent. The file path may be affected by `#line` directives ([§6.5.8](lexical-structure.md#658-line-directives)). -#### 22.5.6.4 The CallerMemberName attribute +#### 23.5.6.4 The CallerMemberName attribute The attribute `System.Runtime.CompilerServices.CallerMemberNameAttribute` is allowed on optional parameters when there is a standard implicit conversion ([§10.4.2](conversions.md#1042-standard-implicit-conversions)) from `string` to the parameter’s type. @@ -826,15 +826,15 @@ For invocations that occur within explicit interface member implementations, onl For invocations that occur within property or event accessors, the member name used is that of the property or event itself. -For invocations that occur within indexer accessors, the member name used is that supplied by an `IndexerNameAttribute` ([§22.6](attributes.md#226-attributes-for-interoperation)) on the indexer member, if present, or the default name `Item` otherwise. +For invocations that occur within indexer accessors, the member name used is that supplied by an `IndexerNameAttribute` ([§23.6](attributes.md#236-attributes-for-interoperation)) on the indexer member, if present, or the default name `Item` otherwise. For invocations that occur within field or event initializers, the member name used is the name of the field or event being initialized. For invocations that occur within declarations of instance constructors, static constructors, finalizers and operators the member name used is implementation-dependent. -### 22.5.7 Code analysis attributes +### 23.5.7 Code analysis attributes -#### 22.5.7.1 General +#### 23.5.7.1 General The attributes in this subclause are used to provide additional information to support a compiler that provides nullability and null-state diagnostics ([§8.9.5](types.md#895-nullabilities-and-null-states)). A compiler isn’t required to perform any null-state diagnostics. The presence or absence of these attributes do not affect the language nor the behavior of a program. A compiler that doesn’t provide null-state diagnostics shall read and ignore the presence of these attributes. A compiler that provides null-state diagnostics shall use the meaning defined in this subclause for any of these attributes which it uses to inform its diagnostics. @@ -842,19 +842,19 @@ The code-analysis attributes are declared in namespace `System.Diagnostics.CodeA **Attribute** | **Meaning** ------------------ | ------------------ -`AllowNull` ([§22.5.7.2](attributes.md#22572-the-allownull-attribute)) | A non-nullable argument may be null. -`DisallowNull` ([§22.5.7.3](attributes.md#22573-the-disallownull-attribute)) | A nullable argument should never be null. -`MaybeNull` ([§22.5.7.6](attributes.md#22576-the-maybenull-attribute)) | A non-nullable return value may be null. -`NotNull` ([§22.5.7.8](attributes.md#22578-the-notnull-attribute)) | A nullable return value will never be null. -`MaybeNullWhen` ([§22.5.7.7](attributes.md#22577-the-maybenullwhen-attribute)) | A non-nullable argument may be null when the method returns the specified `bool` value. -`NotNullWhen` ([§22.5.7.10](attributes.md#225710-the-notnullwhen-attribute)) | A nullable argument won’t be null when the method returns the specified `bool` value. -`NotNullIfNotNull` ([§22.5.7.9](attributes.md#22579-the-notnullifnotnull-attribute)) | A return value isn’t null if the argument for the specified parameter isn’t null. -`DoesNotReturn` ([§22.5.7.4](attributes.md#22574-the-doesnotreturn-attribute)) | This method never returns. -`DoesNotReturnIf` ([§22.5.7.5](attributes.md#22575-the-doesnotreturnif-attribute)) | This method never returns if the associated `bool` parameter has the specified value. +`AllowNull` ([§23.5.7.2](attributes.md#23572-the-allownull-attribute)) | A non-nullable argument may be null. +`DisallowNull` ([§23.5.7.3](attributes.md#23573-the-disallownull-attribute)) | A nullable argument should never be null. +`MaybeNull` ([§23.5.7.6](attributes.md#23576-the-maybenull-attribute)) | A non-nullable return value may be null. +`NotNull` ([§23.5.7.8](attributes.md#23578-the-notnull-attribute)) | A nullable return value will never be null. +`MaybeNullWhen` ([§23.5.7.7](attributes.md#23577-the-maybenullwhen-attribute)) | A non-nullable argument may be null when the method returns the specified `bool` value. +`NotNullWhen` ([§23.5.7.10](attributes.md#235710-the-notnullwhen-attribute)) | A nullable argument won’t be null when the method returns the specified `bool` value. +`NotNullIfNotNull` ([§23.5.7.9](attributes.md#23579-the-notnullifnotnull-attribute)) | A return value isn’t null if the argument for the specified parameter isn’t null. +`DoesNotReturn` ([§23.5.7.4](attributes.md#23574-the-doesnotreturn-attribute)) | This method never returns. +`DoesNotReturnIf` ([§23.5.7.5](attributes.md#23575-the-doesnotreturnif-attribute)) | This method never returns if the associated `bool` parameter has the specified value. -The following subclauses in [§22.5.7.1](attributes.md#22571-general) are conditionally normative. +The following subclauses in [§23.5.7.1](attributes.md#23571-general) are conditionally normative. -#### 22.5.7.2 The AllowNull attribute +#### 23.5.7.2 The AllowNull attribute Specifies that a null value is allowed as an input even if the corresponding type disallows it. @@ -885,7 +885,7 @@ Specifies that a null value is allowed as an input even if the corresponding typ > > without the attribute, a compiler may generate a warning because the non-nullable-typed property appears to be set to a null value. The presence of the attribute suppresses that warning. *end example* -#### 22.5.7.3 The DisallowNull attribute +#### 23.5.7.3 The DisallowNull attribute Specifies that a null value is disallowed as an input even if the corresponding type allows it. @@ -909,7 +909,7 @@ Specifies that a null value is disallowed as an input even if the corresponding > > The get accessor could return the default value of `null`, so a compiler may warn that it must be checked before access. Furthermore, it warns callers that, even though it could be null, callers shouldn’t explicitly set it to null. *end example* -#### 22.5.7.4 The DoesNotReturn attribute +#### 23.5.7.4 The DoesNotReturn attribute Specifies that a given method never returns. @@ -942,7 +942,7 @@ Specifies that a given method never returns. > > The attribute does not change reachability ([§13.2](statements.md#132-end-points-and-reachability)) or definite assignment ([§9.4](variables.md#94-definite-assignment)) analysis based on the presence of this attribute. It is used only to impact nullability warnings. *end example* -#### 22.5.7.5 The DoesNotReturnIf attribute +#### 23.5.7.5 The DoesNotReturnIf attribute Specifies that a given method never returns if the associated `bool` parameter has the specified value. @@ -975,7 +975,7 @@ Specifies that a given method never returns if the associated `bool` parameter h > > *end example* -#### 22.5.7.6 The MaybeNull attribute +#### 23.5.7.6 The MaybeNull attribute Specifies that a non-nullable return value may be null. @@ -998,11 +998,11 @@ Specifies that a non-nullable return value may be null. > > The attribute informs callers that the contract implies a non-nullable type, but the return value may actually be `null`. *end example* -#### 22.5.7.7 The MaybeNullWhen attribute +#### 23.5.7.7 The MaybeNullWhen attribute -Specifies that a non-nullable argument may be `null` when the method returns the specified `bool` value. This is similar to the `MaybeNull` attribute ([§22.5.7.6](attributes.md#22576-the-maybenull-attribute)), but includes a parameter for the specified return value. +Specifies that a non-nullable argument may be `null` when the method returns the specified `bool` value. This is similar to the `MaybeNull` attribute ([§23.5.7.6](attributes.md#23576-the-maybenull-attribute)), but includes a parameter for the specified return value. -#### 22.5.7.8 The NotNull attribute +#### 23.5.7.8 The NotNull attribute Specifies that a nullable value will never be `null` if the method returns (rather than throwing). @@ -1023,7 +1023,7 @@ Specifies that a nullable value will never be `null` if the method returns (rath > > When null reference types are enabled, method `ThrowWhenNull` compiles without warnings. When that method returns, the `value` argument is guaranteed to be not `null`. However, it’s acceptable to call `ThrowWhenNull` with a null reference. *end example* -#### 22.5.7.9 The NotNullIfNotNull attribute +#### 23.5.7.9 The NotNullIfNotNull attribute Specifies that a return value isn’t `null` if the argument for the specified parameter isn’t `null`. @@ -1046,7 +1046,7 @@ Specifies that a return value isn’t `null` if the argument for the specified p > > *end example* -#### 22.5.7.10 The NotNullWhen attribute +#### 23.5.7.10 The NotNullWhen attribute Specifies that a nullable argument won’t be `null` when the method returns the specified `bool` value. @@ -1060,7 +1060,7 @@ Specifies that a nullable argument won’t be `null` when the method returns the > > *end example* -## 22.6 Attributes for interoperation +## 23.6 Attributes for interoperation For interoperation with other languages, an indexer may be implemented using indexed properties. If no `IndexerName` attribute is present for an indexer, then the name `Item` is used by default. The `IndexerName` attribute enables a developer to override this default and specify a different name. diff --git a/standard/basic-concepts.md b/standard/basic-concepts.md index 326809438..df6e4f463 100644 --- a/standard/basic-concepts.md +++ b/standard/basic-concepts.md @@ -53,7 +53,7 @@ Other than the situations listed above, entry point methods behave like those th If the return type of the application’s effective entry point method is `int` and execution completes without resulting in an exception, the value of the `int` returned serves as the application’s ***termination status code***. The purpose of this code is to allow communication of success or failure to the execution environment. If the return type of the effective entry point method is `void` and execution completes without resulting in an exception, the termination status code is `0`. -If the effective entry point method terminates due to an exception ([§21.4](exceptions.md#214-how-exceptions-are-handled)), the exit code is implementation-defined. Additionally, the implementation may provide alternative APIs for specifying the exit code. +If the effective entry point method terminates due to an exception ([§22.4](exceptions.md#224-how-exceptions-are-handled)), the exit code is implementation-defined. Additionally, the implementation may provide alternative APIs for specifying the exit code. Whether or not finalizers ([§15.13](classes.md#1513-finalizers)) are run as part of application termination is implementation-defined. @@ -61,7 +61,7 @@ Whether or not finalizers ([§15.13](classes.md#1513-finalizers)) are run as par ## 7.3 Declarations -Declarations in a C# program define the constituent elements of the program. C# programs are organized using namespaces. These are introduced using namespace declarations ([§14](namespaces.md#14-namespaces)), which can contain type declarations and nested namespace declarations. Type declarations ([§14.7](namespaces.md#147-type-declarations)) are used to define classes ([§15](classes.md#15-classes)), structs ([§16](structs.md#16-structs)), interfaces ([§18](interfaces.md#18-interfaces)), enums ([§19](enums.md#19-enums)), and delegates ([§20](delegates.md#20-delegates)). The kinds of members permitted in a type declaration depend on the form of the type declaration. For instance, class declarations can contain declarations for constants ([§15.4](classes.md#154-constants)), fields ([§15.5](classes.md#155-fields)), methods ([§15.6](classes.md#156-methods)), properties ([§15.7](classes.md#157-properties)), events ([§15.8](classes.md#158-events)), indexers ([§15.9](classes.md#159-indexers)), operators ([§15.10](classes.md#1510-operators)), instance constructors ([§15.11](classes.md#1511-instance-constructors)), static constructors ([§15.12](classes.md#1512-static-constructors)), finalizers ([§15.13](classes.md#1513-finalizers)), and nested types ([§15.3.9](classes.md#1539-nested-types)). +Declarations in a C# program define the constituent elements of the program. C# programs are organized using namespaces. These are introduced using namespace declarations ([§14](namespaces.md#14-namespaces)), which can contain type declarations and nested namespace declarations. Type declarations ([§14.7](namespaces.md#147-type-declarations)) are used to define classes ([§15](classes.md#15-classes)), structs ([§16](structs.md#16-structs)), interfaces ([§19](interfaces.md#19-interfaces)), enums ([§20](enums.md#20-enums)), and delegates ([§21](delegates.md#21-delegates)). The kinds of members permitted in a type declaration depend on the form of the type declaration. For instance, class declarations can contain declarations for constants ([§15.4](classes.md#154-constants)), fields ([§15.5](classes.md#155-fields)), methods ([§15.6](classes.md#156-methods)), properties ([§15.7](classes.md#157-properties)), events ([§15.8](classes.md#158-events)), indexers ([§15.9](classes.md#159-indexers)), operators ([§15.10](classes.md#1510-operators)), instance constructors ([§15.11](classes.md#1511-instance-constructors)), static constructors ([§15.12](classes.md#1512-static-constructors)), finalizers ([§15.13](classes.md#1513-finalizers)), and nested types ([§15.3.9](classes.md#1539-nested-types)). A declaration defines a name in the ***declaration space*** to which the declaration belongs. It is a compile-time error to have two or more declarations that introduce members with the same name in a declaration space, except in the following cases: @@ -89,7 +89,7 @@ There are several different types of declaration spaces, as described in the fol - Each *block*, *switch_block*, *specific_catch_clause*, *iteration_statement* and *using_statement* creates a nested local variable declaration space. - Each *embedded_statement* that is not directly part of a *statement_list* creates a nested local variable declaration space. - Each *switch_section* creates a nested local variable declaration space. However, variables declared directly within the *statement_list* of the *switch_section* (but not within a nested local variable declaration space inside the *statement_list*) are added directly to the local variable declaration space of the enclosing *switch_block*, instead of that of the *switch_section*. - - The syntactic translation of a *query_expression* ([§12.20.3](expressions.md#12203-query-expression-translation)) may introduce one or more lambda expressions. As anonymous functions, each of these creates a local variable declaration space as described above. + - The syntactic translation of a *query_expression* ([§12.21.3](expressions.md#12213-query-expression-translation)) may introduce one or more lambda expressions. As anonymous functions, each of these creates a local variable declaration space as described above. - Each *block* or *switch_block* creates a separate declaration space for labels. Names are introduced into this declaration space through *labeled_statement*s, and the names are referenced through *goto_statement*s. The ***label declaration space*** of a block includes any nested blocks. Thus, within a nested block it is not possible to declare a label with the same name as a label in an enclosing block. > *Note*: The fact that variables declared directly within a *switch_section* are added to the local variable declaration space of the *switch_block* instead of the *switch_section* can lead to surprising code. In the example below, the local variable `y` is in scope within the switch section for the default case, despite the declaration appearing in the switch section for case 0. The local variable `z` is not in scope within the switch section for the default case, as it is introduced in the local variable declaration space for the switch section in which the declaration occurs. @@ -120,7 +120,7 @@ The textual order in which names are declared is generally of no significance. I - Declaration order for field declarations determines the order in which their initializers (if any) are executed ([§15.5.6.2](classes.md#15562-static-field-initialization), [§15.5.6.3](classes.md#15563-instance-field-initialization)). - Local variables shall be defined before they are used ([§7.7](basic-concepts.md#77-scopes)). -- Declaration order for enum member declarations ([§19.4](enums.md#194-enum-members)) is significant when *constant_expression* values are omitted. +- Declaration order for enum member declarations ([§20.4](enums.md#204-enum-members)) is significant when *constant_expression* values are omitted. > *Example*: The declaration space of a namespace is “open ended”, and two namespace declarations with the same fully qualified name contribute to the same declaration space. For example > @@ -243,7 +243,7 @@ The members of `object` ([§8.2.3](types.md#823-the-object-type)) and `string` ( The members of an interface are the members declared in the interface and in all base interfaces of the interface. -> *Note*: The members in class `object` are not, strictly speaking, members of any interface ([§18.4](interfaces.md#184-interface-members)). However, the members in class `object` are available via member lookup in any interface type ([§12.5](expressions.md#125-member-lookup)). *end note* +> *Note*: The members in class `object` are not, strictly speaking, members of any interface ([§19.4](interfaces.md#194-interface-members)). However, the members in class `object` are available via member lookup in any interface type ([§12.5](expressions.md#125-member-lookup)). *end note* ### 7.4.7 Array members @@ -251,7 +251,7 @@ The members of an array are the members inherited from class `System.Array`. ### 7.4.8 Delegate members -A delegate inherits members from class `System.Delegate`. Additionally, it contains a method named `Invoke` with the same return type and parameter list specified in its declaration ([§20.2](delegates.md#202-delegate-declarations)). An invocation of this method shall behave identically to a delegate invocation ([§20.6](delegates.md#206-delegate-invocation)) on the same delegate instance. +A delegate inherits members from class `System.Delegate`. Additionally, it contains a method named `Invoke` with the same return type and parameter list specified in its declaration ([§21.2](delegates.md#212-delegate-declarations)). An invocation of this method shall behave identically to a delegate invocation ([§21.6](delegates.md#216-delegate-invocation)) on the same delegate instance. An implementation may provide additional members, either through inheritance or directly in the delegate itself. @@ -607,19 +607,19 @@ The ***scope*** of a name is the region of program text within which it is possi - The scope of a type parameter declared by a *type_parameter_list* on a *class_declaration* ([§15.2](classes.md#152-class-declarations)) is the *class_base*, *type_parameter_constraints_clause*s, and *class_body* of that *class_declaration*. > *Note*: Unlike members of a class, this scope does not extend to derived classes. *end note* - The scope of a type parameter declared by a *type_parameter_list* on a *struct_declaration* ([§16.2](structs.md#162-struct-declarations)) is the *struct_interfaces*, *type_parameter_constraints_clause*s, and *struct_body* of that *struct_declaration*. -- The scope of a type parameter declared by a *type_parameter_list* on an *interface_declaration* ([§18.2](interfaces.md#182-interface-declarations)) is the *interface_base*, *type_parameter_constraints_clause*s, and *interface_body* of that *interface_declaration*. -- The scope of a type parameter declared by a *type_parameter_list* on a *delegate_declaration* ([§20.2](delegates.md#202-delegate-declarations)) is the *return_type*, *parameter_list*, and *type_parameter_constraints_clause*s of that *delegate_declaration*. +- The scope of a type parameter declared by a *type_parameter_list* on an *interface_declaration* ([§19.2](interfaces.md#192-interface-declarations)) is the *interface_base*, *type_parameter_constraints_clause*s, and *interface_body* of that *interface_declaration*. +- The scope of a type parameter declared by a *type_parameter_list* on a *delegate_declaration* ([§21.2](delegates.md#212-delegate-declarations)) is the *return_type*, *parameter_list*, and *type_parameter_constraints_clause*s of that *delegate_declaration*. - The scope of a type parameter declared by a *type_parameter_list* on a *method_declaration* ([§15.6.1](classes.md#1561-general)) is the *method_declaration*. - The scope of a member declared by a *class_member_declaration* ([§15.3.1](classes.md#1531-general)) is the *class_body* in which the declaration occurs. In addition, the scope of a class member extends to the *class_body* of those derived classes that are included in the accessibility domain ([§7.5.3](basic-concepts.md#753-accessibility-domains)) of the member. - The scope of a member declared by a *struct_member_declaration* ([§16.3](structs.md#163-struct-members)) is the *struct_body* in which the declaration occurs. -- The scope of a member declared by an *enum_member_declaration* ([§19.4](enums.md#194-enum-members)) is the *enum_body* in which the declaration occurs. +- The scope of a member declared by an *enum_member_declaration* ([§20.4](enums.md#204-enum-members)) is the *enum_body* in which the declaration occurs. - The scope of a parameter declared in a *method_declaration* ([§15.6](classes.md#156-methods)) is the *method_body* or *ref_method_body* of that *method_declaration*. - The scope of a parameter declared in an *indexer_declaration* ([§15.9](classes.md#159-indexers)) is the *indexer_body* of that *indexer_declaration*. - The scope of a parameter declared in an *operator_declaration* ([§15.10](classes.md#1510-operators)) is the *operator_body* of that *operator_declaration*. - The scope of a parameter declared in a *constructor_declaration* ([§15.11](classes.md#1511-instance-constructors)) is the *constructor_initializer* and *block* of that *constructor_declaration*. -- The scope of a parameter declared in a *lambda_expression* ([§12.19](expressions.md#1219-anonymous-function-expressions)) is the *lambda_expression_body* of that *lambda_expression*. -- The scope of a parameter declared in an *anonymous_method_expression* ([§12.19](expressions.md#1219-anonymous-function-expressions)) is the *block* of that *anonymous_method_expression*. +- The scope of a parameter declared in a *lambda_expression* ([§12.20](expressions.md#1220-anonymous-function-expressions)) is the *lambda_expression_body* of that *lambda_expression*. +- The scope of a parameter declared in an *anonymous_method_expression* ([§12.20](expressions.md#1220-anonymous-function-expressions)) is the *block* of that *anonymous_method_expression*. - The scope of a label declared in a *labeled_statement* ([§13.5](statements.md#135-labeled-statements)) is the *block* in which the declaration occurs. - The scope of a local variable declared in a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)) is the *block* in which the declaration occurs. - The scope of a local variable declared in a *switch_block* of a `switch` statement ([§13.8.3](statements.md#1383-the-switch-statement)) is the *switch_block*. diff --git a/standard/classes.md b/standard/classes.md index b46746511..66df09bab 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -18,7 +18,7 @@ class_declaration ; ``` -A *class_declaration* consists of an optional set of *attributes* ([§22](attributes.md#22-attributes)), followed by an optional set of *class_modifier*s ([§15.2.2](classes.md#1522-class-modifiers)), followed by an optional `partial` modifier ([§15.2.7](classes.md#1527-partial-type-declarations)), followed by the keyword `class` and an *identifier* that names the class, followed by an optional *type_parameter_list* ([§15.2.3](classes.md#1523-type-parameters)), followed by an optional *class_base* specification ([§15.2.4](classes.md#1524-class-base-specification)), followed by an optional set of *type_parameter_constraints_clause*s ([§15.2.5](classes.md#1525-type-parameter-constraints)), followed by a *class_body* ([§15.2.6](classes.md#1526-class-body)), optionally followed by a semicolon. +A *class_declaration* consists of an optional set of *attributes* ([§23](attributes.md#23-attributes)), followed by an optional set of *class_modifier*s ([§15.2.2](classes.md#1522-class-modifiers)), followed by an optional `partial` modifier ([§15.2.7](classes.md#1527-partial-type-declarations)), followed by the keyword `class` and an *identifier* that names the class, followed by an optional *type_parameter_list* ([§15.2.3](classes.md#1523-type-parameters)), followed by an optional *class_base* specification ([§15.2.4](classes.md#1524-class-base-specification)), followed by an optional set of *type_parameter_constraints_clause*s ([§15.2.5](classes.md#1525-type-parameter-constraints)), followed by a *class_body* ([§15.2.6](classes.md#1526-class-body)), optionally followed by a semicolon. A class declaration shall not supply *type_parameter_constraints_clause*s unless it also supplies a *type_parameter_list*. @@ -44,7 +44,7 @@ class_modifier ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). It is a compile-time error for the same modifier to appear multiple times in a class declaration. @@ -166,7 +166,7 @@ Two partial generic type declarations (in the same program) contribute to the sa #### 15.2.4.1 General -A class declaration may include a *class_base* specification, which defines the direct base class of the class and the interfaces ([§18](interfaces.md#18-interfaces)) directly implemented by the class. +A class declaration may include a *class_base* specification, which defines the direct base class of the class and the interfaces ([§19](interfaces.md#19-interfaces)) directly implemented by the class. ```ANTLR class_base @@ -232,7 +232,7 @@ The base class specified in a class declaration can be a constructed class type The direct base class of a class type shall be at least as accessible as the class type itself ([§7.5.5](basic-concepts.md#755-accessibility-constraints)). For example, it is a compile-time error for a public class to derive from a private or internal class. -The direct base class of a class type shall not be any of the following types: `System.Array`, `System.Delegate`, `System.Enum`, `System.ValueType` or the `dynamic` type. Furthermore, a generic class declaration shall not use `System.Attribute` as a direct or indirect base class ([§22.2.1](attributes.md#2221-general)). +The direct base class of a class type shall not be any of the following types: `System.Array`, `System.Delegate`, `System.Enum`, `System.ValueType` or the `dynamic` type. Furthermore, a generic class declaration shall not use `System.Attribute` as a direct or indirect base class ([§23.2.1](attributes.md#2321-general)). In determining the meaning of the direct base class specification `A` of a class `B`, the direct base class of `B` is temporarily assumed to be `object`, which ensures that the meaning of a base class specification cannot recursively depend on itself. @@ -370,7 +370,7 @@ Typically, each part provides an implementation of the interfaces declared on th > > *end example* -The base interfaces specified in a class declaration can be constructed interface types ([§8.4](types.md#84-constructed-types), [§18.2](interfaces.md#182-interface-declarations)). A base interface cannot be a type parameter on its own, though it can involve the type parameters that are in scope. +The base interfaces specified in a class declaration can be constructed interface types ([§8.4](types.md#84-constructed-types), [§19.2](interfaces.md#192-interface-declarations)). A base interface cannot be a type parameter on its own, though it can involve the type parameters that are in scope. > *Example*: The following code illustrates how a class can implement and extend constructed types: > @@ -384,7 +384,7 @@ The base interfaces specified in a class declaration can be constructed interfac > > *end example* -Interface implementations are discussed further in [§18.6](interfaces.md#186-interface-implementations). +Interface implementations are discussed further in [§19.6](interfaces.md#196-interface-implementations). ### 15.2.5 Type parameter constraints @@ -809,7 +809,7 @@ Nested types may be declared in multiple parts by using the `partial` modifier. > > *end example* -The handling of attributes specified on the type or type parameters of different parts of a partial type declaration is discussed in [§22.3](attributes.md#223-attribute-specification). +The handling of attributes specified on the type or type parameters of different parts of a partial type declaration is discussed in [§23.3](attributes.md#233-attribute-specification). ## 15.3 Class members @@ -1548,9 +1548,9 @@ constant_modifier ; ``` -A *constant_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)), a `new` modifier ([§15.3.5](classes.md#1535-the-new-modifier)), and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)). The attributes and modifiers apply to all of the members declared by the *constant_declaration*. Even though constants are considered static members, a *constant_declaration* neither requires nor allows a `static` modifier. It is an error for the same modifier to appear multiple times in a constant declaration. +A *constant_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)), a `new` modifier ([§15.3.5](classes.md#1535-the-new-modifier)), and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)). The attributes and modifiers apply to all of the members declared by the *constant_declaration*. Even though constants are considered static members, a *constant_declaration* neither requires nor allows a `static` modifier. It is an error for the same modifier to appear multiple times in a constant declaration. -The *type* of a *constant_declaration* specifies the type of the members introduced by the declaration. The type is followed by a list of *constant_declarator*s ([§13.6.3](statements.md#1363-local-constant-declarations)), each of which introduces a new member. A *constant_declarator* consists of an *identifier* that names the member, followed by an “`=`” token, followed by a *constant_expression* ([§12.23](expressions.md#1223-constant-expressions)) that gives the value of the member. +The *type* of a *constant_declaration* specifies the type of the members introduced by the declaration. The type is followed by a list of *constant_declarator*s ([§13.6.3](statements.md#1363-local-constant-declarations)), each of which introduces a new member. A *constant_declarator* consists of an *identifier* that names the member, followed by an “`=`” token, followed by a *constant_expression* ([§12.24](expressions.md#1224-constant-expressions)) that gives the value of the member. The *type* specified in a constant declaration shall be `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, `double`, `decimal`, `bool`, `string`, an *enum_type*, or a *reference_type*. Each *constant_expression* shall yield a value of the target type or of a type that can be converted to the target type by an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)). @@ -1564,7 +1564,7 @@ A constant can itself participate in a *constant_expression*. Thus, a constant m -> *Note*: As described in [§12.23](expressions.md#1223-constant-expressions), a *constant_expression* is an expression that can be fully evaluated at compile-time. Since the only way to create a non-null value of a *reference_type* other than `string` is to apply the `new` operator, and since the `new` operator is not permitted in a *constant_expression*, the only possible value for constants of *reference_type*s other than `string` is `null`. *end note* +> *Note*: As described in [§12.24](expressions.md#1224-constant-expressions), a *constant_expression* is an expression that can be fully evaluated at compile-time. Since the only way to create a non-null value of a *reference_type* other than `string` is to apply the `new` operator, and since the `new` operator is not permitted in a *constant_expression*, the only possible value for constants of *reference_type*s other than `string` is `null`. *end note* When a symbolic name for a constant value is desired, but when the type of that value is not permitted in a constant declaration, or when the value cannot be computed at compile-time by a *constant_expression*, a readonly field ([§15.5.3](classes.md#1553-readonly-fields)) may be used instead. @@ -1654,15 +1654,15 @@ variable_declarator ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). -A *field_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)), a `new` modifier ([§15.3.5](classes.md#1535-the-new-modifier)), a valid combination of the four access modifiers ([§15.3.6](classes.md#1536-access-modifiers)), and a `static` modifier ([§15.5.2](classes.md#1552-static-and-instance-fields)). In addition, a *field_declaration* may include a `readonly` modifier ([§15.5.3](classes.md#1553-readonly-fields)) or a `volatile` modifier ([§15.5.4](classes.md#1554-volatile-fields)), but not both. The attributes and modifiers apply to all of the members declared by the *field_declaration*. It is an error for the same modifier to appear multiple times in a *field_declaration*. +A *field_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)), a `new` modifier ([§15.3.5](classes.md#1535-the-new-modifier)), a valid combination of the four access modifiers ([§15.3.6](classes.md#1536-access-modifiers)), and a `static` modifier ([§15.5.2](classes.md#1552-static-and-instance-fields)). In addition, a *field_declaration* may include a `readonly` modifier ([§15.5.3](classes.md#1553-readonly-fields)) or a `volatile` modifier ([§15.5.4](classes.md#1554-volatile-fields)), but not both. The attributes and modifiers apply to all of the members declared by the *field_declaration*. It is an error for the same modifier to appear multiple times in a *field_declaration*. The *type* of a *field_declaration* specifies the type of the members introduced by the declaration. The type is followed by a list of *variable_declarator*s, each of which introduces a new member. A *variable_declarator* consists of an *identifier* that names that member, optionally followed by an “`=`” token and a *variable_initializer* ([§15.5.6](classes.md#1556-variable-initializers)) that gives the initial value of that member. The *type* of a field shall be at least as accessible as the field itself ([§7.5.5](basic-concepts.md#755-accessibility-constraints)). -The value of a field is obtained in an expression using a *simple_name* ([§12.8.4](expressions.md#1284-simple-names)), a *member_access* ([§12.8.7](expressions.md#1287-member-access)) or a base_access ([§12.8.15](expressions.md#12815-base-access)). The value of a non-readonly field is modified using an *assignment* ([§12.21](expressions.md#1221-assignment-operators)). The value of a non-readonly field can be both obtained and modified using postfix increment and decrement operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators)) and prefix increment and decrement operators ([§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators)). +The value of a field is obtained in an expression using a *simple_name* ([§12.8.4](expressions.md#1284-simple-names)), a *member_access* ([§12.8.7](expressions.md#1287-member-access)) or a base_access ([§12.8.15](expressions.md#12815-base-access)). The value of a non-readonly field is modified using an *assignment* ([§12.22](expressions.md#1222-assignment-operators)). The value of a non-readonly field can be both obtained and modified using postfix increment and decrement operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators)) and prefix increment and decrement operators ([§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators)). A field declaration that declares multiple fields is equivalent to multiple declarations of single fields with the same attributes, modifiers, and type. @@ -2128,12 +2128,12 @@ ref_method_body Grammar notes: -- *unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +- *unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). - when recognising a *method_body* if both the *null_conditional_invocation_expression* and *expression* alternatives are applicable then the former shall be chosen. > *Note*: The overlapping of, and priority between, alternatives here is solely for descriptive convenience; the grammar rules could be elaborated to remove the overlap. ANTLR, and other grammar systems, adopt the same convenience and so *method_body* has the specified semantics automatically. *end note* -A *method_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)) and one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.6.3](classes.md#1563-static-and-instance-methods)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods)), `override` ([§15.6.5](classes.md#1565-override-methods)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods)), `extern` ([§15.6.8](classes.md#1568-external-methods)) and `async` ([§15.14](classes.md#1514-async-functions)). Additionally a *method_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.4.12](structs.md#16412-methods)). +A *method_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)) and one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.6.3](classes.md#1563-static-and-instance-methods)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods)), `override` ([§15.6.5](classes.md#1565-override-methods)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods)), `extern` ([§15.6.8](classes.md#1568-external-methods)) and `async` ([§15.14](classes.md#1514-async-functions)). Additionally a *method_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.4.12](structs.md#16412-methods)). A declaration has a valid combination of modifiers if all of the following are true: @@ -2158,9 +2158,9 @@ The *ref_return_type* of a returns-by-ref method declaration specifies the type A generic method is a method whose declaration includes a *type_parameter_list*. This specifies the type parameters for the method. The optional *type_parameter_constraints_clause*s specify the constraints for the type parameters. -A generic *method_declaration*, either with an `override` modifier, or for an explicit interface member implementation, inherits type parameter constraints from the overridden method or interface member respectively. Such declarations may only have *type_parameter_constraints_clause*s containing the *primary_constraint*s `class` and `struct`, the meaning of which in this context is defined in [§15.6.5](classes.md#1565-override-methods) and [§18.6.2](interfaces.md#1862-explicit-interface-member-implementations) for overriding methods and explicit interface implementations respectively. +A generic *method_declaration*, either with an `override` modifier, or for an explicit interface member implementation, inherits type parameter constraints from the overridden method or interface member respectively. Such declarations may only have *type_parameter_constraints_clause*s containing the *primary_constraint*s `class` and `struct`, the meaning of which in this context is defined in [§15.6.5](classes.md#1565-override-methods) and [§19.6.2](interfaces.md#1962-explicit-interface-member-implementations) for overriding methods and explicit interface implementations respectively. -The *member_name* specifies the name of the method. Unless the method is an explicit interface member implementation ([§18.6.2](interfaces.md#1862-explicit-interface-member-implementations)), the *member_name* is simply an *identifier*. +The *member_name* specifies the name of the method. Unless the method is an explicit interface member implementation ([§19.6.2](interfaces.md#1962-explicit-interface-member-implementations)), the *member_name* is simply an *identifier*. For an explicit interface member implementation, the *member_name* consists of an *interface_type* followed by a “`.`” and an *identifier*. In this case, the declaration shall include no modifiers other than (possibly) `extern` or `async`. @@ -2230,7 +2230,7 @@ parameter_array The parameter list consists of one or more comma-separated parameters of which only the last may be a *parameter_array*. -A *fixed_parameter* consists of an optional set of *attributes* ([§22](attributes.md#22-attributes)); an optional `in`, `out`, `ref`, or `this` modifier; a *type*; an *identifier*; and an optional *default_argument*. Each *fixed_parameter* declares a parameter of the given type with the given name. The `this` modifier designates the method as an extension method and is only allowed on the first parameter of a static method in a non-generic, non-nested static class. If the parameter is a `struct` type or a type parameter constrained to a `struct`, the `this` modifier may be combined with either the `ref` or `in` modifier, but not the `out` modifier. Extension methods are further described in [§15.6.10](classes.md#15610-extension-methods). A *fixed_parameter* with a *default_argument* is known as an ***optional parameter***, whereas a *fixed_parameter* without a *default_argument* is a ***required parameter***. A required parameter shall not appear after an optional parameter in a *parameter_list*. +A *fixed_parameter* consists of an optional set of *attributes* ([§23](attributes.md#23-attributes)); an optional `in`, `out`, `ref`, or `this` modifier; a *type*; an *identifier*; and an optional *default_argument*. Each *fixed_parameter* declares a parameter of the given type with the given name. The `this` modifier designates the method as an extension method and is only allowed on the first parameter of a static method in a non-generic, non-nested static class. If the parameter is a `struct` type or a type parameter constrained to a `struct`, the `this` modifier may be combined with either the `ref` or `in` modifier, but not the `out` modifier. Extension methods are further described in [§15.6.10](classes.md#15610-extension-methods). A *fixed_parameter* with a *default_argument* is known as an ***optional parameter***, whereas a *fixed_parameter* without a *default_argument* is a ***required parameter***. A required parameter shall not appear after an optional parameter in a *parameter_list*. A parameter with a `ref`, `out` or `this` modifier cannot have a *default_argument*. An input parameter may have a *default_argument*. The *expression* in a *default_argument* shall be one of the following: @@ -2240,9 +2240,9 @@ A parameter with a `ref`, `out` or `this` modifier cannot have a *default_argume The *expression* shall be implicitly convertible by an identity or nullable conversion to the type of the parameter. -If optional parameters occur in an implementing partial method declaration ([§15.6.9](classes.md#1569-partial-methods)), an explicit interface member implementation ([§18.6.2](interfaces.md#1862-explicit-interface-member-implementations)), a single-parameter indexer declaration ([§15.9](classes.md#159-indexers)), or in an operator declaration ([§15.10.1](classes.md#15101-general)) a compiler should give a warning, since these members can never be invoked in a way that permits arguments to be omitted. +If optional parameters occur in an implementing partial method declaration ([§15.6.9](classes.md#1569-partial-methods)), an explicit interface member implementation ([§19.6.2](interfaces.md#1962-explicit-interface-member-implementations)), a single-parameter indexer declaration ([§15.9](classes.md#159-indexers)), or in an operator declaration ([§15.10.1](classes.md#15101-general)) a compiler should give a warning, since these members can never be invoked in a way that permits arguments to be omitted. -A *parameter_array* consists of an optional set of *attributes* ([§22](attributes.md#22-attributes)), a `params` modifier, an *array_type*, and an *identifier*. A parameter array declares a single parameter of the given array type with the given name. The *array_type* of a parameter array shall be a single-dimensional array type ([§17.2](arrays.md#172-array-types)). In a method invocation, a parameter array permits either a single argument of the given array type to be specified, or it permits zero or more arguments of the array element type to be specified. Parameter arrays are described further in [§15.6.2.4](classes.md#15624-parameter-arrays). +A *parameter_array* consists of an optional set of *attributes* ([§23](attributes.md#23-attributes)), a `params` modifier, an *array_type*, and an *identifier*. A parameter array declares a single parameter of the given array type with the given name. The *array_type* of a parameter array shall be a single-dimensional array type ([§17.2](arrays.md#172-array-types)). In a method invocation, a parameter array permits either a single argument of the given array type to be specified, or it permits zero or more arguments of the array element type to be specified. Parameter arrays are described further in [§15.6.2.4](classes.md#15624-parameter-arrays). A *parameter_array* may occur after an optional parameter, but cannot have a default value – the omission of arguments for a *parameter_array* would instead result in the creation of an empty array. @@ -3326,18 +3326,18 @@ ref_property_body ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). -A *property_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.7.2](classes.md#1572-static-and-instance-properties)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), `override` ([§15.6.5](classes.md#1565-override-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)) and `extern` ([§15.6.8](classes.md#1568-external-methods)). Additionally a *property_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.4.11](structs.md#16411-properties)). +A *property_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.7.2](classes.md#1572-static-and-instance-properties)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), `override` ([§15.6.5](classes.md#1565-override-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)) and `extern` ([§15.6.8](classes.md#1568-external-methods)). Additionally a *property_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.4.11](structs.md#16411-properties)). - The first declares a non-ref-valued property. Its value has type *type*. This kind of property may be readable and/or writeable. - The second declares a ref-valued property. Its value is a *variable_reference* ([§9.5](variables.md#95-variable-references)), that may be `readonly`, to a variable of type *type*. This kind of property is only readable. -A *property_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.7.2](classes.md#1572-static-and-instance-properties)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), `override` ([§15.6.5](classes.md#1565-override-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), and `extern` ([§15.6.8](classes.md#1568-external-methods)) modifiers. +A *property_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.7.2](classes.md#1572-static-and-instance-properties)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), `override` ([§15.6.5](classes.md#1565-override-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods), [§15.7.6](classes.md#1576-virtual-sealed-override-and-abstract-accessors)), and `extern` ([§15.6.8](classes.md#1568-external-methods)) modifiers. Property declarations are subject to the same rules as method declarations ([§15.6](classes.md#156-methods)) with regard to valid combinations of modifiers. -The *member_name* ([§15.6.1](classes.md#1561-general)) specifies the name of the property. Unless the property is an explicit interface member implementation, the *member_name* is simply an *identifier*. For an explicit interface member implementation ([§18.6.2](interfaces.md#1862-explicit-interface-member-implementations)), the *member_name* consists of an *interface_type* followed by a “`.`” and an *identifier*. +The *member_name* ([§15.6.1](classes.md#1561-general)) specifies the name of the property. Unless the property is an explicit interface member implementation, the *member_name* is simply an *identifier*. For an explicit interface member implementation ([§19.6.2](interfaces.md#1962-explicit-interface-member-implementations)), the *member_name* consists of an *interface_type* followed by a “`.`” and an *identifier*. The *type* of a property shall be at least as accessible as the property itself ([§7.5.5](basic-concepts.md#755-accessibility-constraints)). @@ -3469,7 +3469,7 @@ A get accessor for a ref-valued property corresponds to a parameterless method w The body of a get accessor for a ref-valued property shall conform to the rules for ref-valued methods described in [§15.6.11](classes.md#15611-method-body). -A set accessor corresponds to a method with a single value parameter of the property type and a `void` return type. The implicit parameter of a set accessor is always named `value`. When a property is referenced as the target of an assignment ([§12.21](expressions.md#1221-assignment-operators)), or as the operand of `++` or `–-` ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators), [§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators)), the set accessor is invoked with an argument that provides the new value ([§12.21.2](expressions.md#12212-simple-assignment)). The body of a set accessor shall conform to the rules for `void` methods described in [§15.6.11](classes.md#15611-method-body). In particular, return statements in the set accessor body are not permitted to specify an expression. Since a set accessor implicitly has a parameter named `value`, it is a compile-time error for a local variable or constant declaration in a set accessor to have that name. +A set accessor corresponds to a method with a single value parameter of the property type and a `void` return type. The implicit parameter of a set accessor is always named `value`. When a property is referenced as the target of an assignment ([§12.22](expressions.md#1222-assignment-operators)), or as the operand of `++` or `–-` ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators), [§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators)), the set accessor is invoked with an argument that provides the new value ([§12.22.2](expressions.md#12222-simple-assignment)). The body of a set accessor shall conform to the rules for `void` methods described in [§15.6.11](classes.md#15611-method-body). In particular, return statements in the set accessor body are not permitted to specify an expression. Since a set accessor implicitly has a parameter named `value`, it is a compile-time error for a local variable or constant declaration in a set accessor to have that name. Based on the presence or absence of the get and set accessors, a property is classified as follows: @@ -3842,8 +3842,8 @@ The presence of an *accessor_modifier* never affects member lookup ([§12.5](exp Once a particular non-ref-valued property or non-ref-valued indexer has been selected, the accessibility domains of the specific accessors involved are used to determine if that usage is valid: - If the usage is as a value ([§12.2.2](expressions.md#1222-values-of-expressions)), the get accessor shall exist and be accessible. -- If the usage is as the target of a simple assignment ([§12.21.2](expressions.md#12212-simple-assignment)), the set accessor shall exist and be accessible. -- If the usage is as the target of compound assignment ([§12.21.4](expressions.md#12214-compound-assignment)), or as the target of the `++` or `--` operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators), [§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators)), both the get accessors and the set accessor shall exist and be accessible. +- If the usage is as the target of a simple assignment ([§12.22.2](expressions.md#12222-simple-assignment)), the set accessor shall exist and be accessible. +- If the usage is as the target of compound assignment ([§12.22.4](expressions.md#12224-compound-assignment)), or as the target of the `++` or `--` operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators), [§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators)), both the get accessors and the set accessor shall exist and be accessible. > *Example*: In the following example, the property `A.Text` is hidden by the property `B.Text`, even in contexts where only the set accessor is called. In contrast, the property `B.Count` is not accessible to class `M`, so the accessible property `A.Count` is used instead. > @@ -4071,9 +4071,9 @@ remove_accessor_declaration ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). -An *event_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.6.3](classes.md#1563-static-and-instance-methods), [§15.8.4](classes.md#1584-static-and-instance-events)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods), [§15.8.5](classes.md#1585-virtual-sealed-override-and-abstract-accessors)), `override` ([§15.6.5](classes.md#1565-override-methods), [§15.8.5](classes.md#1585-virtual-sealed-override-and-abstract-accessors)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods), [§15.8.5](classes.md#1585-virtual-sealed-override-and-abstract-accessors)) and `extern` ([§15.6.8](classes.md#1568-external-methods)) modifiers. Additionally an *event_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.4.12](structs.md#16412-methods)). +An *event_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `static` ([§15.6.3](classes.md#1563-static-and-instance-methods), [§15.8.4](classes.md#1584-static-and-instance-events)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods), [§15.8.5](classes.md#1585-virtual-sealed-override-and-abstract-accessors)), `override` ([§15.6.5](classes.md#1565-override-methods), [§15.8.5](classes.md#1585-virtual-sealed-override-and-abstract-accessors)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods), [§15.8.5](classes.md#1585-virtual-sealed-override-and-abstract-accessors)) and `extern` ([§15.6.8](classes.md#1568-external-methods)) modifiers. Additionally an *event_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.4.12](structs.md#16412-methods)). Event declarations are subject to the same rules as method declarations ([§15.6](classes.md#156-methods)) with regard to valid combinations of modifiers. @@ -4093,7 +4093,7 @@ An event can be used as the left operand of the `+=` and `-=` operators. These The only operations that are permitted on an event by code that is outside the type in which that event is declared, are `+=` and `-=`. Therefore, while such code can add and remove handlers for an event, it cannot directly obtain or modify the underlying list of event handlers. -In an operation of the form `x += y` or `x –= y`, when `x` is an event the result of the operation has type `void` ([§12.21.5](expressions.md#12215-event-assignment)) (as opposed to having the type of `x`, with the value of `x` after the assignment, as for other the `+=` and `-=` operators defined on non-event types). This prevents external code from indirectly examining the underlying delegate of an event. +In an operation of the form `x += y` or `x –= y`, when `x` is an event the result of the operation has type `void` ([§12.22.5](expressions.md#12225-event-assignment)) (as opposed to having the type of `x`, with the value of `x` after the assignment, as for other the `+=` and `-=` operators defined on non-event types). This prevents external code from indirectly examining the underlying delegate of an event. > *Example*: The following example shows how event handlers are attached to instances of the `Button` class: > @@ -4137,7 +4137,7 @@ In an operation of the form `x += y` or `x –= y`, when `x` is an event the ### 15.8.2 Field-like events -Within the program text of the class or struct that contains the declaration of an event, certain events can be used like fields. To be used in this way, an event shall not be abstract or extern, and shall not explicitly include *event_accessor_declaration*s. Such an event can be used in any context that permits a field. The field contains a delegate ([§20](delegates.md#20-delegates)), which refers to the list of event handlers that have been added to the event. If no event handlers have been added, the field contains `null`. +Within the program text of the class or struct that contains the declaration of an event, certain events can be used like fields. To be used in this way, an event shall not be abstract or extern, and shall not explicitly include *event_accessor_declaration*s. Such an event can be used in any context that permits a field. The field contains a delegate ([§21](delegates.md#21-delegates)), which refers to the list of event handlers that have been added to the event. If no event handlers have been added, the field contains `null`. > *Example*: In the following code > @@ -4354,14 +4354,14 @@ ref_indexer_body ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). -An *indexer_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods)), `override` ([§15.6.5](classes.md#1565-override-methods)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods)) and `extern` ([§15.6.8](classes.md#1568-external-methods)) modifiers. Additionally an *indexer_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.4.12](structs.md#16412-methods)). +An *indexer_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods)), `override` ([§15.6.5](classes.md#1565-override-methods)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods)) and `extern` ([§15.6.8](classes.md#1568-external-methods)) modifiers. Additionally an *indexer_declaration* that is contained directly by a *struct_declaration* may include the `readonly` modifier ([§16.4.12](structs.md#16412-methods)). - The first declares a non-ref-valued indexer. Its value has type *type*. This kind of indexer may be readable and/or writeable. - The second declares a ref-valued indexer. Its value is a *variable_reference* ([§9.5](variables.md#95-variable-references)), that may be `readonly`, to a variable of type *type*. This kind of indexer is only readable. -An *indexer_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods)), `override` ([§15.6.5](classes.md#1565-override-methods)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods)), and `extern` ([§15.6.8](classes.md#1568-external-methods)) modifiers. +An *indexer_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)) and any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), the `new` ([§15.3.5](classes.md#1535-the-new-modifier)), `virtual` ([§15.6.4](classes.md#1564-virtual-methods)), `override` ([§15.6.5](classes.md#1565-override-methods)), `sealed` ([§15.6.6](classes.md#1566-sealed-methods)), `abstract` ([§15.6.7](classes.md#1567-abstract-methods)), and `extern` ([§15.6.8](classes.md#1568-external-methods)) modifiers. Indexer declarations are subject to the same rules as method declarations ([§15.6](classes.md#156-methods)) with regard to valid combinations of modifiers, with the one exception being that the `static` modifier is not permitted on an indexer declaration. @@ -4528,7 +4528,7 @@ When an indexer declaration includes an `extern` modifier, the indexer is said t Indexers and properties are very similar in concept, but differ in the following ways: - A property is identified by its name, whereas an indexer is identified by its signature. -- A property is accessed through a *simple_name* ([§12.8.4](expressions.md#1284-simple-names)) or a *member_access* ([§12.8.7](expressions.md#1287-member-access)), whereas an indexer element is accessed through an *element_access* ([§12.8.12.3](expressions.md#128123-indexer-access)). +- A property is accessed through a *simple_name* ([§12.8.4](expressions.md#1284-simple-names)) or a *member_access* ([§12.8.7](expressions.md#1287-member-access)), whereas an indexer element is accessed through an *element_access* ([§12.8.12.4](expressions.md#128124-indexer-access)). - A property can be a static member, whereas an indexer is always an instance member. - A get accessor of a property corresponds to a method with no parameters, whereas a get accessor of an indexer corresponds to a method with the same parameter list as the indexer. - A set accessor of a property corresponds to a method with a single parameter named `value`, whereas a set accessor of an indexer corresponds to a method with the same parameter list as the indexer, plus an additional parameter named `value`. @@ -4598,7 +4598,7 @@ operator_body ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). *Note*: The prefix logical negation ([§12.9.4](expressions.md#1294-logical-negation-operator)) and postfix null-forgiving operators ([§12.8.9](expressions.md#1289-null-forgiving-expressions)), while represented by the same lexical token (`!`), are distinct. The latter is not an overloadable operator. *end note* @@ -4634,7 +4634,7 @@ The following rules apply to unary operator declarations, where `T` denotes the The signature of a unary operator consists of the operator token (`+`, `-`, `!`, `~`, `++`, `--`, `true`, or `false`) and the type of the single parameter. The return type is not part of a unary operator’s signature, nor is the name of the parameter. -The `true` and `false` unary operators require pair-wise declaration. A compile-time error occurs if a class declares one of these operators without also declaring the other. The `true` and `false` operators are described further in [§12.24](expressions.md#1224-boolean-expressions). +The `true` and `false` unary operators require pair-wise declaration. A compile-time error occurs if a class declares one of these operators without also declaring the other. The `true` and `false` operators are described further in [§12.25](expressions.md#1225-boolean-expressions). > *Example*: The following example shows an implementation and subsequent usage of operator++ for an integer vector class: > @@ -4669,7 +4669,7 @@ The `true` and `false` unary operators require pair-wise declaration. A compile- > } > ``` > -> Note how the operator method returns the value produced by adding 1 to the operand, just like the postfix increment and decrement operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators)), and the prefix increment and decrement operators ([§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators)). Unlike in C++, this method should not modify the value of its operand directly as this would violate the standard semantics of the postfix increment operator ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators)). +> Note how the operator method returns the value produced by adding 1 to the operand, just like the postfix increment and decrement operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators)), and the prefix increment and decrement operators ([§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators)). Unlike in C++, this method should not modify the value of its operand directly as this would violate the standard semantics of the postfix increment operator ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators)). > > *end example* @@ -4678,7 +4678,7 @@ The `true` and `false` unary operators require pair-wise declaration. A compile- The following rules apply to binary operator declarations, where `T` denotes the instance type of the class or struct that contains the operator declaration: - A binary non-shift operator shall take two parameters, at least one of which shall have type `T` or `T?`, and can return any type. -- A binary `<<` or `>>` operator ([§12.11](expressions.md#1211-shift-operators)) shall take two parameters, the first of which shall have type `T` or `T?` and the second of which shall have type `int` or `int?`, and can return any type. +- A binary `<<` or `>>` operator ([§12.12](expressions.md#1212-shift-operators)) shall take two parameters, the first of which shall have type `T` or `T?` and the second of which shall have type `int` or `int?`, and can return any type. The signature of a binary operator consists of the operator token (`+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, `>>`, `==`, `!=`, `>`, `<`, `>=`, or `<=`) and the types of the two parameters. The return type and the names of the parameters are not part of a binary operator’s signature. @@ -4856,9 +4856,9 @@ constructor_body ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). -A *constructor_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)), any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), and an `extern` ([§15.6.8](classes.md#1568-external-methods)) modifier. A constructor declaration is not permitted to include the same modifier multiple times. +A *constructor_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)), any one of the permitted kinds of declared accessibility ([§15.3.6](classes.md#1536-access-modifiers)), and an `extern` ([§15.6.8](classes.md#1568-external-methods)) modifier. A constructor declaration is not permitted to include the same modifier multiple times. The *identifier* of a *constructor_declarator* shall name the class in which the instance constructor is declared. If any other name is specified, a compile-time error occurs. @@ -5126,9 +5126,9 @@ static_constructor_body ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). -A *static_constructor_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)) and an `extern` modifier ([§15.6.8](classes.md#1568-external-methods)). +A *static_constructor_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)) and an `extern` modifier ([§15.6.8](classes.md#1568-external-methods)). The *identifier* of a *static_constructor_declaration* shall name the class in which the static constructor is declared. If any other name is specified, a compile-time error occurs. @@ -5289,9 +5289,9 @@ finalizer_body ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). -A *finalizer_declaration* may include a set of *attributes* ([§22](attributes.md#22-attributes)). +A *finalizer_declaration* may include a set of *attributes* ([§23](attributes.md#23-attributes)). The *identifier* of a *finalizer_declarator* shall name the class in which the finalizer is declared. If any other name is specified, a compile-time error occurs. @@ -5387,13 +5387,13 @@ A compiler shall behave as if this method, and overrides of it, do not exist at > > *end example* -For a discussion of the behavior when an exception is thrown from a finalizer, see [§21.4](exceptions.md#214-how-exceptions-are-handled). +For a discussion of the behavior when an exception is thrown from a finalizer, see [§22.4](exceptions.md#224-how-exceptions-are-handled). ## 15.14 Async Functions ### 15.14.1 General -A method ([§15.6](classes.md#156-methods)), anonymous function ([§12.19](expressions.md#1219-anonymous-function-expressions)), or local function ([§13.6.4](statements.md#1364-local-function-declarations)) with the `async` modifier is called an ***async function***. In general, the term ***async*** is used to describe any kind of function that has the `async` modifier. +A method ([§15.6](classes.md#156-methods)), anonymous function ([§12.20](expressions.md#1220-anonymous-function-expressions)), or local function ([§13.6.4](statements.md#1364-local-function-declarations)) with the `async` modifier is called an ***async function***. In general, the term ***async*** is used to describe any kind of function that has the `async` modifier. It is a compile-time error for the parameter list of an async function to specify any `in`, `out`, or `ref` parameters, or any parameter of a `ref struct` type. @@ -5401,7 +5401,7 @@ The *return_type* of an async method shall be either `void`, a ***task type***, An async method returning a task type is said to be ***task-returning***. -Task types can vary in their exact definition, but from the language’s point of view, a task type is in one of the states *incomplete*, *succeeded* or *faulted*. A *faulted* task records a pertinent exception. A *succeeded* `«TaskType»` records a result of type `T`. Task types are awaitable, and tasks can therefore be the operands of await expressions ([§12.9.8](expressions.md#1298-await-expressions)). +Task types can vary in their exact definition, but from the language’s point of view, a task type is in one of the states *incomplete*, *succeeded* or *faulted*. A *faulted* task records a pertinent exception. A *succeeded* `«TaskType»` records a result of type `T`. Task types are awaitable, and tasks can therefore be the operands of await expressions ([§12.9.9](expressions.md#1299-await-expressions)). > *Example*: The task type `MyTask` is associated with the task builder type `MyTaskMethodBuilder` and the awaiter type `Awaiter`: > @@ -5428,7 +5428,7 @@ A task builder type is a class or struct type that corresponds to a specific tas > *Note:* If the task type is declared `internal`, the the corresponding builder type must also be declared `internal` and be defined in the same assembly. If the task type is nested inside another type, the task builder type must also be nested in that same type. *end note* -An async function has the ability to suspend evaluation by means of await expressions ([§12.9.8](expressions.md#1298-await-expressions)) in its body. Evaluation may later be resumed at the point of the suspending await expression by means of a ***resumption delegate***. The resumption delegate is of type `System.Action`, and when it is invoked, evaluation of the async function invocation will resume from the await expression where it left off. The ***current caller*** of an async function invocation is the original caller if the function invocation has never been suspended or the most recent caller of the resumption delegate otherwise. +An async function has the ability to suspend evaluation by means of await expressions ([§12.9.9](expressions.md#1299-await-expressions)) in its body. Evaluation may later be resumed at the point of the suspending await expression by means of a ***resumption delegate***. The resumption delegate is of type `System.Action`, and when it is invoked, evaluation of the async function invocation will resume from the await expression where it left off. The ***current caller*** of an async function invocation is the original caller if the function invocation has never been suspended or the most recent caller of the resumption delegate otherwise. ### 15.14.2 Task-type builder pattern diff --git a/standard/clauses.json b/standard/clauses.json index 740c816da..a605d645c 100644 --- a/standard/clauses.json +++ b/standard/clauses.json @@ -25,6 +25,7 @@ "classes.md", "structs.md", "arrays.md", + "ranges.md", "interfaces.md", "enums.md", "delegates.md", @@ -32,8 +33,7 @@ "attributes.md" ], "UnsafeClauses": [ - "unsafe-code.md", - "ranges.md" + "unsafe-code.md" ], "Annexes": [ "grammar.md", diff --git a/standard/conversions.md b/standard/conversions.md index bca951adf..0c047927c 100644 --- a/standard/conversions.md +++ b/standard/conversions.md @@ -64,7 +64,7 @@ The following conversions are classified as implicit conversions: - Default literal conversions ([§10.2.16](conversions.md#10216-default-literal-conversions)) - Implicit throw conversions ([§10.2.17](conversions.md#10217-implicit-throw-conversions)) -Implicit conversions can occur in a variety of situations, including function member invocations ([§12.6.6](expressions.md#1266-function-member-invocation)), cast expressions ([§12.9.7](expressions.md#1297-cast-expressions)), and assignments ([§12.21](expressions.md#1221-assignment-operators)). +Implicit conversions can occur in a variety of situations, including function member invocations ([§12.6.6](expressions.md#1266-function-member-invocation)), cast expressions ([§12.9.8](expressions.md#1298-cast-expressions)), and assignments ([§12.22](expressions.md#1222-assignment-operators)). The pre-defined implicit conversions always succeed and never cause exceptions to be thrown. @@ -113,7 +113,7 @@ An identity conversion converts from any type to the same type or a type that is All identity conversions are symmetric. If an identity conversion exists from `T₁` to `T₂`, then an identity conversion exists from `T₂` to `T₁`. Two types are *identity convertible* when an identity conversion exists between two types. -In most cases, an identity conversion has no effect at runtime. However, since floating point operations may be performed at higher precision than prescribed by their type ([§8.3.7](types.md#837-floating-point-types)), assignment of their results may result in a loss of precision, and explicit casts are guaranteed to reduce precision to what is prescribed by the type ([§12.9.7](expressions.md#1297-cast-expressions)). +In most cases, an identity conversion has no effect at runtime. However, since floating point operations may be performed at higher precision than prescribed by their type ([§8.3.7](types.md#837-floating-point-types)), assignment of their results may result in a loss of precision, and explicit casts are guaranteed to reduce precision to what is prescribed by the type ([§12.9.8](expressions.md#1298-cast-expressions)). ### 10.2.3 Implicit numeric conversions @@ -136,7 +136,7 @@ There are no predefined implicit conversions to the `char` type, so values of th ### 10.2.4 Implicit enumeration conversions -An implicit enumeration conversion permits a *constant_expression* ([§12.23](expressions.md#1223-constant-expressions)) with any integer type and the value zero to be converted to any *enum_type* and to any *nullable_value_type* whose underlying type is an *enum_type*. In the latter case the conversion is evaluated by converting to the underlying *enum_type* and wrapping the result ([§8.3.12](types.md#8312-nullable-value-types)). +An implicit enumeration conversion permits a *constant_expression* ([§12.24](expressions.md#1224-constant-expressions)) with any integer type and the value zero to be converted to any *enum_type* and to any *nullable_value_type* whose underlying type is an *enum_type*. In the latter case the conversion is evaluated by converting to the underlying *enum_type* and wrapping the result ([§8.3.12](types.md#8312-nullable-value-types)). ### 10.2.5 Implicit interpolated string conversions @@ -167,7 +167,7 @@ The implicit reference conversions are: - From any *delegate_type* to `System.Delegate` and the interfaces it implements. - From the null literal ([§6.4.5.7](lexical-structure.md#6457-the-null-literal)) to any reference-type. - From any *reference_type* to a *reference_type* `T` if it has an implicit identity or reference conversion to a *reference_type* `T₀` and `T₀` has an identity conversion to `T`. -- From any *reference_type* to an interface or delegate type `T` if it has an implicit identity or reference conversion to an interface or delegate type `T₀` and `T₀` is variance-convertible ([§18.2.3.3](interfaces.md#18233-variance-conversion)) to `T`. +- From any *reference_type* to an interface or delegate type `T` if it has an implicit identity or reference conversion to an interface or delegate type `T₀` and `T₀` is variance-convertible ([§19.2.3.3](interfaces.md#19233-variance-conversion)) to `T`. - Implicit conversions involving type parameters that are known to be reference types. See [§10.2.12](conversions.md#10212-implicit-conversions-involving-type-parameters) for more details on implicit conversions involving type parameters. The implicit reference conversions are those conversions between *reference_type*s that can be proven to always succeed, and therefore require no checks at run-time. @@ -185,7 +185,7 @@ A boxing conversion permits a *value_type* to be implicitly converted to a *refe - From any *enum_type* to the type `System.Enum`. - From any *non_nullable_value_type* to any *interface_type* implemented by the *non_nullable_value_type*. - From any *non_nullable_value_type* to any *interface_type* `I` such that there is a boxing conversion from the *non_nullable_value_type* to another *interface_type* `I₀`, and `I₀` has an identity conversion to `I`. -- From any *non_nullable_value_type* to any *interface_type* `I` such that there is a boxing conversion from the *non_nullable_value_type* to another *interface_type* `I₀`, and `I₀` is variance-convertible ([§18.2.3.3](interfaces.md#18233-variance-conversion)) to `I`. +- From any *non_nullable_value_type* to any *interface_type* `I` such that there is a boxing conversion from the *non_nullable_value_type* to another *interface_type* `I₀`, and `I₀` is variance-convertible ([§19.2.3.3](interfaces.md#19233-variance-conversion)) to `I`. - From any *nullable_value_type* to any *reference_type* where there is a boxing conversion from the underlying type of the *nullable_value_type* to the *reference_type.* - From a type parameter that is not known to be a reference type to any type such that the conversion is permitted by [§10.2.12](conversions.md#10212-implicit-conversions-involving-type-parameters). @@ -315,7 +315,7 @@ This implicit conversion seemingly violates the advice in the beginning of [§10 An implicit constant expression conversion permits the following conversions: -- A *constant_expression* ([§12.23](expressions.md#1223-constant-expressions)) of type `int` can be converted to type `sbyte`, `byte`, `short`, `ushort`, `uint`, or `ulong`, provided the value of the *constant_expression* is within the range of the destination type. +- A *constant_expression* ([§12.24](expressions.md#1224-constant-expressions)) of type `int` can be converted to type `sbyte`, `byte`, `short`, `ushort`, `uint`, or `ulong`, provided the value of the *constant_expression* is within the range of the destination type. - A *constant_expression* of type `long` can be converted to type `ulong`, provided the value of the *constant_expression* is not negative. ### 10.2.12 Implicit conversions involving type parameters @@ -339,7 +339,7 @@ For a *type_parameter* `T` that is *not* known to be a reference type, there is The following further implicit conversions exist for a given type parameter `T`: - From `T` to a reference type `S` if it has an implicit conversion to a reference type `S₀` and `S₀` has an identity conversion to `S`. At run-time, the conversion is executed the same way as the conversion to `S₀`. -- From `T` to an interface type `I` if it has an implicit conversion to an interface type `I₀`, and `I₀` is variance-convertible to `I` ([§18.2.3.3](interfaces.md#18233-variance-conversion)). At run-time, if `T` is a value type, the conversion is executed as a boxing conversion. Otherwise, the conversion is executed as an implicit reference conversion or identity conversion. +- From `T` to an interface type `I` if it has an implicit conversion to an interface type `I₀`, and `I₀` is variance-convertible to `I` ([§19.2.3.3](interfaces.md#19233-variance-conversion)). At run-time, if `T` is a value type, the conversion is executed as a boxing conversion. Otherwise, the conversion is executed as an implicit reference conversion or identity conversion. In all cases, the rules ensure that a conversion is executed as a boxing conversion if and only if at run-time the conversion is from a value type to a reference type. @@ -397,7 +397,7 @@ The following conversions are classified as explicit conversions: - Explicit type parameter conversions ([§10.3.8](conversions.md#1038-explicit-conversions-involving-type-parameters)) - User-defined explicit conversions ([§10.3.9](conversions.md#1039-user-defined-explicit-conversions)) -Explicit conversions can occur in cast expressions ([§12.9.7](expressions.md#1297-cast-expressions)). +Explicit conversions can occur in cast expressions ([§12.9.8](expressions.md#1298-cast-expressions)). The set of explicit conversions includes all implicit conversions. @@ -422,7 +422,7 @@ The explicit numeric conversions are the conversions from a *numeric_type* to an - From `double` to `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, or `decimal`. - From `decimal` to `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, or `double`. -Because the explicit conversions include all implicit and explicit numeric conversions, it is always possible to convert from any *numeric_type* to any other *numeric_type* using a cast expression ([§12.9.7](expressions.md#1297-cast-expressions)). +Because the explicit conversions include all implicit and explicit numeric conversions, it is always possible to convert from any *numeric_type* to any other *numeric_type* using a cast expression ([§12.9.8](expressions.md#1298-cast-expressions)). The explicit numeric conversions possibly lose information or possibly cause exceptions to be thrown. An explicit numeric conversion is processed as follows: @@ -483,7 +483,7 @@ The explicit reference conversions are: - From `System.Collections.Generic.IList`, `System.Collections.Generic.IReadOnlyList`, and their base interfaces to a single-dimensional array type `T[]`, provided that there is an identity conversion or explicit reference conversion from `S` to T. - From `System.Delegate` and the interfaces it implements to any *delegate_type*. - From a reference type `S` to a reference type `T` if it has an explicit reference conversion from `S` to a reference type `T₀` and `T₀` and there is an identity conversion from `T₀` to `T`. -- From a reference type `S` to an interface or delegate type `T` if it there is an explicit reference conversion from `S` to an interface or delegate type `T₀` and either `T₀` is variance-convertible to `T` or `T` is variance-convertible to `T₀` [§18.2.3.3](interfaces.md#18233-variance-conversion). +- From a reference type `S` to an interface or delegate type `T` if it there is an explicit reference conversion from `S` to an interface or delegate type `T₀` and either `T₀` is variance-convertible to `T` or `T` is variance-convertible to `T₀` [§19.2.3.3](interfaces.md#19233-variance-conversion). - From `D` to `D` where `D` is a generic delegate type, `D` is not compatible with or identical to `D`, and for each type parameter `Xᵢ` of `D` the following holds: - If `Xᵢ` is invariant, then `Sᵢ` is identical to `Tᵢ`. - If `Xᵢ` is covariant, then there is an identity conversion, implicit reference conversion or explicit reference conversion from `Sᵢ` to `Tᵢ`. @@ -509,7 +509,7 @@ An unboxing conversion permits a *reference_type* to be explicitly converted to - From the type `System.Enum` to any *enum_type*. - From any *interface_type* to any *non_nullable_value_type* that implements the *interface_type*. - From any *interface_type* `I` to any *non_nullable_value_type* where there is an unboxing conversion from an *interface_type* `I₀` to the *non_nullable_value-type* and an identity conversion from `I` to `I₀`. -- From any *interface_type* `I` to any *non_nullable_value_type* where there is an unboxing conversion from an *interface_type* `I₀` to the *non_nullable_value_type* and either `I₀` is variance_convertible to `I` or `I` is variance-convertible to `I₀` ([§18.2.3.3](interfaces.md#18233-variance-conversion)). +- From any *interface_type* `I` to any *non_nullable_value_type* where there is an unboxing conversion from an *interface_type* `I₀` to the *non_nullable_value_type* and either `I₀` is variance_convertible to `I` or `I` is variance-convertible to `I₀` ([§19.2.3.3](interfaces.md#19233-variance-conversion)). - From any *reference_type* to any *nullable_value_type* where there is an unboxing conversion from *reference_type* to the underlying *non_nullable_value_type* of the *nullable_value_type*. - From a type parameter which is not known to be a value type to any type such that the conversion is permitted by [§10.3.8](conversions.md#1038-explicit-conversions-involving-type-parameters). @@ -752,7 +752,7 @@ Given a user-defined conversion operator that converts from a non-nullable value ### 10.7.1 General -An *anonymous_method_expression* or *lambda_expression* is classified as an anonymous function ([§12.19](expressions.md#1219-anonymous-function-expressions)). The expression does not have a type, but can be implicitly converted to a compatible delegate type. Some lambda expressions may also be implicitly converted to a compatible expression tree type. +An *anonymous_method_expression* or *lambda_expression* is classified as an anonymous function ([§12.20](expressions.md#1220-anonymous-function-expressions)). The expression does not have a type, but can be implicitly converted to a compatible delegate type. Some lambda expressions may also be implicitly converted to a compatible expression tree type. Specifically, an anonymous function `F` is compatible with a delegate type `D` provided: @@ -900,14 +900,14 @@ Not every lambda expression can be converted to expression tree types. The conve ## 10.8 Method group conversions -An implicit conversion exists from a method group ([§12.2](expressions.md#122-expression-classifications)) to a compatible delegate type ([§20.4](delegates.md#204-delegate-compatibility)). If `D` is a delegate type, and `E` is an expression that is classified as a method group, then `D` is compatible with `E` if and only if `E` contains at least one method that is applicable in its normal form ([§12.6.4.2](expressions.md#12642-applicable-function-member)) to any argument list ([§12.6.2](expressions.md#1262-argument-lists)) having types and modifiers matching the parameter types and modifiers of `D`, as described in the following. +An implicit conversion exists from a method group ([§12.2](expressions.md#122-expression-classifications)) to a compatible delegate type ([§21.4](delegates.md#214-delegate-compatibility)). If `D` is a delegate type, and `E` is an expression that is classified as a method group, then `D` is compatible with `E` if and only if `E` contains at least one method that is applicable in its normal form ([§12.6.4.2](expressions.md#12642-applicable-function-member)) to any argument list ([§12.6.2](expressions.md#1262-argument-lists)) having types and modifiers matching the parameter types and modifiers of `D`, as described in the following. The compile-time application of the conversion from a method group `E` to a delegate type `D` is described in the following. - A single method `M` is selected corresponding to a method invocation ([§12.8.10.2](expressions.md#128102-method-invocations)) of the form `E(A)`, with the following modifications: - The argument list `A` is a list of expressions, each classified as a variable and with the type and modifier (`in`, `out`, or `ref`) of the corresponding parameter in the *parameter_list* of `D` — excepting parameters of type `dynamic`, where the corresponding expression has the type `object` instead of `dynamic`. - The candidate methods considered are only those methods that are applicable in their normal form and do not omit any optional parameters ([§12.6.4.2](expressions.md#12642-applicable-function-member)). Thus, candidate methods are ignored if they are applicable only in their expanded form, or if one or more of their optional parameters do not have a corresponding parameter in `D`. -- A conversion is considered to exist if the algorithm of [§12.8.10.2](expressions.md#128102-method-invocations) produces a single best method `M` which is compatible ([§20.4](delegates.md#204-delegate-compatibility)) with `D`. +- A conversion is considered to exist if the algorithm of [§12.8.10.2](expressions.md#128102-method-invocations) produces a single best method `M` which is compatible ([§21.4](delegates.md#214-delegate-compatibility)) with `D`. - If the selected method `M` is an instance method, the instance expression associated with `E` determines the target object of the delegate. - If the selected method `M` is an extension method which is denoted by means of a member access on an instance expression, that instance expression determines the target object of the delegate. - The result of the conversion is a value of type `D`, namely a delegate that refers to the selected method and target object. @@ -1002,4 +1002,4 @@ the target object of the delegate is determined from the instance expression ass - Otherwise, the selected method is part of a static method call, and the target object of the delegate is `null`. - A delegate instance of delegate type `D` is obtained with a reference to the method that was determined at compile-time and a reference to the target object computed above, as follows: - The conversion is permitted (but not required) to use an existing delegate instance that already contains these references. - - If an existing instance was not reused, a new one is created ([§20.5](delegates.md#205-delegate-instantiation)). If there is not enough memory available to allocate the new instance, a `System.OutOfMemoryException` is thrown. Otherwise the instance is initialized with the given references. + - If an existing instance was not reused, a new one is created ([§21.5](delegates.md#215-delegate-instantiation)). If there is not enough memory available to allocate the new instance, a `System.OutOfMemoryException` is thrown. Otherwise the instance is initialized with the given references. diff --git a/standard/delegates.md b/standard/delegates.md index d68014f08..0b3c91af3 100644 --- a/standard/delegates.md +++ b/standard/delegates.md @@ -1,12 +1,12 @@ -# 20 Delegates +# 21 Delegates -## 20.1 General +## 21.1 General A delegate declaration defines a class that is derived from the class `System.Delegate`. A delegate instance encapsulates an ***invocation list***, which is a list of one or more methods, each of which is referred to as a ***callable entity***. For instance methods, a callable entity consists of an instance and a method on that instance. For static methods, a callable entity consists of just a method. Invoking a delegate instance with an appropriate set of arguments causes each of the delegate’s callable entities to be invoked with the given set of arguments. -> *Note*: An interesting and useful property of a delegate instance is that it does not know or care about the classes of the methods it encapsulates; all that matters is that those methods be compatible ([§20.4](delegates.md#204-delegate-compatibility)) with the delegate’s type. This makes delegates perfectly suited for “anonymous” invocation. *end note* +> *Note*: An interesting and useful property of a delegate instance is that it does not know or care about the classes of the methods it encapsulates; all that matters is that those methods be compatible ([§21.4](delegates.md#214-delegate-compatibility)) with the delegate’s type. This makes delegates perfectly suited for “anonymous” invocation. *end note* -## 20.2 Delegate declarations +## 21.2 Delegate declarations A *delegate_declaration* is a *type_declaration* ([§14.7](namespaces.md#147-type-declarations)) that declares a new delegate type. @@ -33,7 +33,7 @@ delegate_modifier ; ``` -*unsafe_modifier* is defined in [§23.2](unsafe-code.md#232-unsafe-contexts). +*unsafe_modifier* is defined in [§24.2](unsafe-code.md#242-unsafe-contexts). It is a compile-time error for the same modifier to appear multiple times in a delegate declaration. @@ -53,11 +53,11 @@ The *return_type* of a returns-by-value or returns-no-value delegate declaration The *ref_return_type* of a returns-by-ref delegate declaration specifies the type of the variable referenced by the *variable_reference* ([§9.5](variables.md#95-variable-references)) returned by the delegate. -The optional *variant_type_parameter_list* ([§18.2.3](interfaces.md#1823-variant-type-parameter-lists)) specifies the type parameters to the delegate itself. +The optional *variant_type_parameter_list* ([§19.2.3](interfaces.md#1923-variant-type-parameter-lists)) specifies the type parameters to the delegate itself. -The return type of a delegate type shall be either `void`, or output-safe ([§18.2.3.2](interfaces.md#18232-variance-safety)). +The return type of a delegate type shall be either `void`, or output-safe ([§19.2.3.2](interfaces.md#19232-variance-safety)). -All the parameter types of a delegate type shall be input-safe ([§18.2.3.2](interfaces.md#18232-variance-safety)). In addition, any output or reference parameter types shall also be output-safe. +All the parameter types of a delegate type shall be input-safe ([§19.2.3.2](interfaces.md#19232-variance-safety)). In addition, any output or reference parameter types shall also be output-safe. > *Note*: Output parameters are required to be input-safe due to common implementation restrictions. *end note* @@ -79,17 +79,17 @@ Delegate types in C# are name equivalent, not structurally equivalent. Like other generic type declarations, type arguments shall be given to create a constructed delegate type. The parameter types and return type of a constructed delegate type are created by substituting, for each type parameter in the delegate declaration, the corresponding type argument of the constructed delegate type. -The only way to declare a delegate type is via a *delegate_declaration*. Every delegate type is a reference type that is derived from `System.Delegate`. The members required for every delegate type are detailed in [§20.3](delegates.md#203-delegate-members). Delegate types are implicitly `sealed`, so it is not permissible to derive any type from a delegate type. It is also not permissible to declare a non-delegate class type deriving from `System.Delegate`. `System.Delegate` is not itself a delegate type; it is a class type from which all delegate types are derived. +The only way to declare a delegate type is via a *delegate_declaration*. Every delegate type is a reference type that is derived from `System.Delegate`. The members required for every delegate type are detailed in [§21.3](delegates.md#213-delegate-members). Delegate types are implicitly `sealed`, so it is not permissible to derive any type from a delegate type. It is also not permissible to declare a non-delegate class type deriving from `System.Delegate`. `System.Delegate` is not itself a delegate type; it is a class type from which all delegate types are derived. -## 20.3 Delegate members +## 21.3 Delegate members -Every delegate type inherits members from the `Delegate` class as described in [§15.3.4](classes.md#1534-inheritance). In addition, every delegate type shall provide a non-generic `Invoke` method whose parameter list matches the *parameter_list* in the delegate declaration, whose return type matches the *return_type* or *ref_return_type* in the delegate declaration, and for returns-by-ref delegates whose *ref_kind* matches that in the delegate declaration. The `Invoke` method shall be at least as accessible as the containing delegate type. Calling the `Invoke` method on a delegate type is semantically equivalent to using the delegate invocation syntax ([§20.6](delegates.md#206-delegate-invocation)) . +Every delegate type inherits members from the `Delegate` class as described in [§15.3.4](classes.md#1534-inheritance). In addition, every delegate type shall provide a non-generic `Invoke` method whose parameter list matches the *parameter_list* in the delegate declaration, whose return type matches the *return_type* or *ref_return_type* in the delegate declaration, and for returns-by-ref delegates whose *ref_kind* matches that in the delegate declaration. The `Invoke` method shall be at least as accessible as the containing delegate type. Calling the `Invoke` method on a delegate type is semantically equivalent to using the delegate invocation syntax ([§21.6](delegates.md#216-delegate-invocation)) . Implementations may define additional members in the delegate type. Except for instantiation, any operation that can be applied to a class or class instance can also be applied to a delegate class or instance, respectively. In particular, it is possible to access members of the `System.Delegate` type via the usual member access syntax. -## 20.4 Delegate compatibility +## 21.4 Delegate compatibility A method or delegate type `M` is ***compatible*** with a delegate type `D` if all of the following are true: @@ -98,7 +98,7 @@ A method or delegate type `M` is ***compatible*** with a delegate type `D` if al - For each by-reference parameter, the parameter type in `D` is the same as the parameter type in `M`. - One of the following is true: - `D` and `M` are both *returns-no-value*. - - `D` and `M` are returns-by-value ([§15.6.1](classes.md#1561-general), [§20.2](delegates.md#202-delegate-declarations)), and an identity or implicit reference conversion exists from the return type of `M` to the return type of `D`. + - `D` and `M` are returns-by-value ([§15.6.1](classes.md#1561-general), [§21.2](delegates.md#212-delegate-declarations)), and an identity or implicit reference conversion exists from the return type of `M` to the return type of `D`. - `D` and `M` are both returns-by-ref, an identity conversion exists between the return type of `M` and the return type of `D`, and both have the same *ref_kind*. This definition of compatibility allows covariance in return type and contravariance in parameter types. @@ -176,7 +176,7 @@ This definition of compatibility allows covariance in return type and contravari > > *end note* -## 20.5 Delegate instantiation +## 21.5 Delegate instantiation An instance of a delegate is created by a *delegate_creation_expression* ([§12.8.17.5](expressions.md#128175-delegate-creation-expressions)), a conversion to a delegate type, delegate combination or delegate removal. The newly created delegate instance then refers to one or more of: @@ -214,7 +214,7 @@ The set of methods encapsulated by a delegate instance is called an *invocation When a new delegate is created from a single delegate the resultant invocation list has just one entry, which is the source delegate ([§12.8.17.5](expressions.md#128175-delegate-creation-expressions)). -Delegates are combined using the binary `+` ([§12.10.5](expressions.md#12105-addition-operator)) and `+=` operators ([§12.21.4](expressions.md#12214-compound-assignment)). A delegate can be removed from a combination of delegates, using the binary `-` ([§12.10.6](expressions.md#12106-subtraction-operator)) and `-=` operators ([§12.21.4](expressions.md#12214-compound-assignment)). Delegates can be compared for equality ([§12.12.9](expressions.md#12129-delegate-equality-operators)). +Delegates are combined using the binary `+` ([§12.11.5](expressions.md#12115-addition-operator)) and `+=` operators ([§12.22.4](expressions.md#12224-compound-assignment)). A delegate can be removed from a combination of delegates, using the binary `-` ([§12.11.6](expressions.md#12116-subtraction-operator)) and `-=` operators ([§12.22.4](expressions.md#12224-compound-assignment)). Delegates can be compared for equality ([§12.13.9](expressions.md#12139-delegate-equality-operators)). > *Example*: The following example shows the instantiation of a number of delegates, and their corresponding invocation lists: > @@ -252,7 +252,7 @@ Delegates are combined using the binary `+` ([§12.10.5](expressions.md#12105-a > When creating a delegate from another delegate with a *delegate_creation_expression* the result has an invocation list with a different structure from the original, but which results in the same methods being invoked in the same order. When `td3` is created from `cd3` its invocation list has just one member, but that member is a list of the methods `M1` and `M2` and those methods are invoked by `td3` in the same order as they are invoked by `cd3`. Similarly when `td4` is instantiated its invocation list has just two entries but it invokes the three methods `M1`, `M2`, and `M1`, in that order just as `cd4` does. > > The structure of the invocation list affects delegate subtraction. Delegate `cd6`, created by subtracting `cd2` (which invokes `M2`) from `cd4` (which invokes `M1`, `M2`, and `M1`) invokes `M1` and `M1`. However delegate `td6`, created by subtracting `cd2` (which invokes `M2`) from `td4` (which invokes `M1`, `M2`, and `M1`) still invokes `M1`, `M2` and `M1`, in that order, as `M2` is not a single entry in the list but a member of a nested list. -> For more examples of combining (as well as removing) delegates, see [§20.6](delegates.md#206-delegate-invocation). +> For more examples of combining (as well as removing) delegates, see [§21.6](delegates.md#216-delegate-invocation). > > *end example* @@ -260,7 +260,7 @@ Once instantiated, a delegate instance always refers to the same invocation list > *Note*: Remember, when two delegates are combined, or one is removed from another, a new delegate results with its own invocation list; the invocation lists of the delegates combined or removed remain unchanged. *end note* -## 20.6 Delegate invocation +## 21.6 Delegate invocation C# provides special syntax for invoking a delegate. When a non-`null` delegate instance whose invocation list contains one entry is invoked, it invokes the one method with the same arguments it was given and returns the same value as the referred-to method. (See [§12.8.10.4](expressions.md#128104-delegate-invocations) for detailed information on delegate invocation.) If an exception occurs during the invocation of such a delegate, and that exception is not caught within the method that was invoked, the search for an exception catch clause continues in the method that called the delegate, as if that method had directly called the method to which that delegate referred. diff --git a/standard/documentation-comments.md b/standard/documentation-comments.md index c63e028ea..a6dbfbde9 100644 --- a/standard/documentation-comments.md +++ b/standard/documentation-comments.md @@ -12,7 +12,7 @@ This specification suggests a set of standard tags to be used in documentation c ## D.2 Introduction -Comments having a certain form can be used to direct a tool to produce XML from those comments and the source code elements that they precede. Such comments are *Single_Line_Comment*s ([§6.3.3](lexical-structure.md#633-comments)) that start with three slashes (`///`), or *Delimited_Comment*s ([§6.3.3](lexical-structure.md#633-comments)) that start with a slash and two asterisks (`/**`). They must immediately precede a user-defined type or a member that they annotate. Attribute sections ([§22.3](attributes.md#223-attribute-specification)) are considered part of declarations, so documentation comments must precede attributes applied to a type or member. +Comments having a certain form can be used to direct a tool to produce XML from those comments and the source code elements that they precede. Such comments are *Single_Line_Comment*s ([§6.3.3](lexical-structure.md#633-comments)) that start with three slashes (`///`), or *Delimited_Comment*s ([§6.3.3](lexical-structure.md#633-comments)) that start with a slash and two asterisks (`/**`). They must immediately precede a user-defined type or a member that they annotate. Attribute sections ([§23.3](attributes.md#233-attribute-specification)) are considered part of declarations, so documentation comments must precede attributes applied to a type or member. For expository purposes, the format of document comments is shown below as two grammar rules: *Single_Line_Doc_Comment* and *Delimited_Doc_Comment*. However, these rules are *not* part of the C\# grammar, but rather, they represent particular formats of *Single_Line_Comment* and *Delimited_Comment* lexer rules, respectively. diff --git a/standard/enums.md b/standard/enums.md index 94d7a1d9a..967037253 100644 --- a/standard/enums.md +++ b/standard/enums.md @@ -1,6 +1,6 @@ -# 19 Enums +# 20 Enums -## 19.1 General +## 20.1 General An ***enum type*** is a distinct value type ([§8.3](types.md#83-value-types)) that declares a set of named constants. @@ -20,7 +20,7 @@ An ***enum type*** is a distinct value type ([§8.3](types.md#83-value-types)) t > > *end example* -## 19.2 Enum declarations +## 20.2 Enum declarations An enum declaration declares a new enum type. An enum declaration begins with the keyword `enum`, and defines the name, accessibility, underlying type, and members of the enum. @@ -76,7 +76,7 @@ An enum declaration that does not explicitly declare an underlying type has an u An enum declaration cannot include a type parameter list, but any enum nested inside a generic class declaration or a generic struct declaration is a generic enum declaration, since type arguments for the containing type shall be supplied to create a constructed type ([§8.4](types.md#84-constructed-types)). -## 19.3 Enum modifiers +## 20.3 Enum modifiers An *enum_declaration* may optionally include a sequence of enum modifiers: @@ -94,7 +94,7 @@ It is a compile-time error for the same modifier to appear multiple times in an The modifiers of an enum declaration have the same meaning as those of a class declaration ([§15.2.2](classes.md#1522-class-modifiers)). However, the `abstract`, and `sealed`, and `static` modifiers are not permitted in an enum declaration. Enums cannot be abstract and do not permit derivation. -## 19.4 Enum members +## 20.4 Enum members The body of an enum type declaration defines zero or more enum members, which are the named constants of the enum type. No two enum members can have the same name. @@ -224,26 +224,26 @@ The associated value of an enum member shall not, directly or indirectly, use th Enum members are named and scoped in a manner exactly analogous to fields within classes. The scope of an enum member is the body of its containing enum type. Within that scope, enum members can be referred to by their simple name. From all other code, the name of an enum member shall be qualified with the name of its enum type. Enum members do not have any declared accessibility—an enum member is accessible if its containing enum type is accessible. -## 19.5 The System.Enum type +## 20.5 The System.Enum type The type `System.Enum` is the abstract base class of all enum types (this is distinct and different from the underlying type of the enum type), and the members inherited from `System.Enum` are available in any enum type. A boxing conversion ([§10.2.9](conversions.md#1029-boxing-conversions)) exists from any enum type to `System.Enum`, and an unboxing conversion ([§10.3.7](conversions.md#1037-unboxing-conversions)) exists from `System.Enum` to any enum type. Note that `System.Enum` is not itself an *enum_type*. Rather, it is a *class_type* from which all *enum_type*s are derived. The type `System.Enum` inherits from the type `System.ValueType` ([§8.3.2](types.md#832-the-systemvaluetype-type)), which, in turn, inherits from type `object`. At run-time, a value of type `System.Enum` can be `null` or a reference to a boxed value of any enum type. -## 19.6 Enum values and operations +## 20.6 Enum values and operations Each enum type defines a distinct type; an explicit enumeration conversion ([§10.3.3](conversions.md#1033-explicit-enumeration-conversions)) is required to convert between an enum type and an integral type, or between two enum types. The set of values of the enum type is the same as the set of values of the underlying type and is not restricted to the values of the named constants. Any value of the underlying type of an enum can be cast to the enum type, and is a distinct valid value of that enum type. -Enum members have the type of their containing enum type (except within other enum member initializers: see [§19.4](enums.md#194-enum-members)). The value of an enum member declared in enum type `E` with associated value `v` is `(E)v`. +Enum members have the type of their containing enum type (except within other enum member initializers: see [§20.4](enums.md#204-enum-members)). The value of an enum member declared in enum type `E` with associated value `v` is `(E)v`. The following operators can be used on values of enum types: -- `==`, `!=`, `<`, `>`, `<=`, `>=` ([§12.12.6](expressions.md#12126-enumeration-comparison-operators)) -- binary `+` ([§12.10.5](expressions.md#12105-addition-operator)) -- binary `-` ([§12.10.6](expressions.md#12106-subtraction-operator)) -- `^`, `&`, `|` ([§12.13.3](expressions.md#12133-enumeration-logical-operators)) +- `==`, `!=`, `<`, `>`, `<=`, `>=` ([§12.13.6](expressions.md#12136-enumeration-comparison-operators)) +- binary `+` ([§12.11.5](expressions.md#12115-addition-operator)) +- binary `-` ([§12.11.6](expressions.md#12116-subtraction-operator)) +- `^`, `&`, `|` ([§12.14.3](expressions.md#12143-enumeration-logical-operators)) - `~` ([§12.9.5](expressions.md#1295-bitwise-complement-operator)) -- `++`, `--` ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators) and [§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators)) -- `sizeof` ([§23.6.9](unsafe-code.md#2369-the-sizeof-operator)) +- `++`, `--` ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators) and [§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators)) +- `sizeof` ([§24.6.9](unsafe-code.md#2469-the-sizeof-operator)) Every enum type automatically derives from the class `System.Enum` (which, in turn, derives from `System.ValueType` and `object`). Thus, inherited methods and properties of this class can be used on values of an enum type. diff --git a/standard/exceptions.md b/standard/exceptions.md index a2a7305b0..127ba0963 100644 --- a/standard/exceptions.md +++ b/standard/exceptions.md @@ -1,18 +1,18 @@ -# 21 Exceptions +# 22 Exceptions -## 21.1 General +## 22.1 General Exceptions in C# provide a structured, uniform, and type-safe way of handling both system level and application-level error conditions. -## 21.2 Causes of exceptions +## 22.2 Causes of exceptions Exceptions can be thrown in two different ways. - A `throw` statement ([§13.10.6](statements.md#13106-the-throw-statement)) throws an exception immediately and unconditionally. Control never reaches the statement immediately following the `throw`. -- Certain exceptional conditions that arise during the processing of C# statements and expressions cause an exception to be thrown in certain circumstances when the operation cannot be completed normally. See [§21.5](exceptions.md#215-common-exception-classes) for a list of the various exceptions that can be thrown in this way. - > *Example*: An integer division operation ([§12.10.3](expressions.md#12103-division-operator)) throws a `System.DivideByZeroException` if the denominator is zero. *end example* +- Certain exceptional conditions that arise during the processing of C# statements and expressions cause an exception to be thrown in certain circumstances when the operation cannot be completed normally. See [§22.5](exceptions.md#225-common-exception-classes) for a list of the various exceptions that can be thrown in this way. + > *Example*: An integer division operation ([§12.11.3](expressions.md#12113-division-operator)) throws a `System.DivideByZeroException` if the denominator is zero. *end example* -## 21.3 The System.Exception class +## 22.3 The System.Exception class The `System.Exception` class is the base type of all exceptions. This class has a few notable properties that all exceptions share: @@ -21,11 +21,11 @@ The `System.Exception` class is the base type of all exceptions. This class has The value of these properties can be specified in calls to the instance constructor for `System.Exception`. -## 21.4 How exceptions are handled +## 22.4 How exceptions are handled Exceptions are handled by a `try` statement ([§13.11](statements.md#1311-the-try-statement)). -When an exception is thrown ([§21.2](exceptions.md#212-causes-of-exceptions)), the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing `try` statement, and the associated `catch` clauses of the `try` statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing `try` statement that encloses the point of the call to the current method. This search continues until a `catch` clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A `catch` clause that doesn’t name an exception class can handle any exception. +When an exception is thrown ([§22.2](exceptions.md#222-causes-of-exceptions)), the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing `try` statement, and the associated `catch` clauses of the `try` statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing `try` statement that encloses the point of the call to the current method. This search continues until a `catch` clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A `catch` clause that doesn’t name an exception class can handle any exception. Once a matching `catch` clause is found, the system prepares to transfer control to the first statement of the `catch` clause. Before execution of the `catch` clause begins, the system first executes, in order, any `finally` clauses that were associated with `try` statements more nested that than the one that caught the exception. @@ -35,7 +35,7 @@ If no matching `catch` clause is found: - Otherwise, if an exception occurs during finalizer execution, and that exception is not caught, then the behavior is unspecified. - Otherwise, if the search for matching `catch` clauses reaches the code that initially started the thread, then execution of the thread is terminated. The impact of such termination is implementation-defined. -## 21.5 Common exception classes +## 22.5 Common exception classes The following exceptions are thrown by certain C# operations. diff --git a/standard/expressions.md b/standard/expressions.md index c64fb4cc7..88e5729bc 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -17,17 +17,17 @@ The result of an expression is classified as one of the following: - A tuple. Every tuple has a fixed number of elements, each with an expression and an optional tuple element name. - A property access. Every property access has an associated type, namely the type of the property. Furthermore, a property access may have an associated instance expression. When an accessor of an instance property access is invoked, the result of evaluating the instance expression becomes the instance represented by `this` ([§12.8.14](expressions.md#12814-this-access)). - An indexer access. Every indexer access has an associated type, namely the element type of the indexer. Furthermore, an indexer access has an associated instance expression and an associated argument list. When an accessor of an indexer access is invoked, the result of evaluating the instance expression becomes the instance represented by `this` ([§12.8.14](expressions.md#12814-this-access)), and the result of evaluating the argument list becomes the parameter list of the invocation. -- Nothing. This occurs when the expression is an invocation of a method with a return type of `void`. An expression classified as nothing is only valid in the context of a *statement_expression* ([§13.7](statements.md#137-expression-statements)) or as the body of a *lambda_expression* ([§12.19](expressions.md#1219-anonymous-function-expressions)). +- Nothing. This occurs when the expression is an invocation of a method with a return type of `void`. An expression classified as nothing is only valid in the context of a *statement_expression* ([§13.7](statements.md#137-expression-statements)) or as the body of a *lambda_expression* ([§12.20](expressions.md#1220-anonymous-function-expressions)). For expressions which occur as subexpressions of larger expressions, with the noted restrictions, the result can also be classified as one of the following: - A namespace. An expression with this classification can only appear as the left-hand side of a *member_access* ([§12.8.7](expressions.md#1287-member-access)). In any other context, an expression classified as a namespace causes a compile-time error. - A type. An expression with this classification can only appear as the left-hand side of a *member_access* ([§12.8.7](expressions.md#1287-member-access)). In any other context, an expression classified as a type causes a compile-time error. - A method group, which is a set of overloaded methods resulting from a member lookup ([§12.5](expressions.md#125-member-lookup)). A method group may have an associated instance expression and an associated type argument list. When an instance method is invoked, the result of evaluating the instance expression becomes the instance represented by `this` ([§12.8.14](expressions.md#12814-this-access)). A method group is permitted in an *invocation_expression* ([§12.8.10](expressions.md#12810-invocation-expressions)) or a *delegate_creation_expression* ([§12.8.17.5](expressions.md#128175-delegate-creation-expressions)), and can be implicitly converted to a compatible delegate type ([§10.8](conversions.md#108-method-group-conversions)). In any other context, an expression classified as a method group causes a compile-time error. -- An event access. Every event access has an associated type, namely the type of the event. Furthermore, an event access may have an associated instance expression. An event access may appear as the left operand of the `+=` and `-=` operators ([§12.21.5](expressions.md#12215-event-assignment)). In any other context, an expression classified as an event access causes a compile-time error. When an accessor of an instance event access is invoked, the result of evaluating the instance expression becomes the instance represented by `this` ([§12.8.14](expressions.md#12814-this-access)). +- An event access. Every event access has an associated type, namely the type of the event. Furthermore, an event access may have an associated instance expression. An event access may appear as the left operand of the `+=` and `-=` operators ([§12.22.5](expressions.md#12225-event-assignment)). In any other context, an expression classified as an event access causes a compile-time error. When an accessor of an instance event access is invoked, the result of evaluating the instance expression becomes the instance represented by `this` ([§12.8.14](expressions.md#12814-this-access)). - A throw expression, which may be used in several contexts to throw an exception in an expression. A throw expression may be converted by an implicit conversion to any type. -A property access or indexer access is always reclassified as a value by performing an invocation of the get accessor or the set accessor. The particular accessor is determined by the context of the property or indexer access: If the access is the target of an assignment, the set accessor is invoked to assign a new value ([§12.21.2](expressions.md#12212-simple-assignment)). Otherwise, the get accessor is invoked to obtain the current value ([§12.2.2](expressions.md#1222-values-of-expressions)). +A property access or indexer access is always reclassified as a value by performing an invocation of the get accessor or the set accessor. The particular accessor is determined by the context of the property or indexer access: If the access is the target of an assignment, the set accessor is invoked to assign a new value ([§12.22.2](expressions.md#12222-simple-assignment)). Otherwise, the get accessor is invoked to obtain the current value ([§12.2.2](expressions.md#1222-values-of-expressions)). An ***instance accessor*** is a property access on an instance, an event access on an instance, or an indexer access. @@ -149,20 +149,20 @@ The precedence of an operator is established by the definition of its associated > | ----------------- | ------------------------------- | -------------------------------------------------------| > | [§12.8](expressions.md#128-primary-expressions) | Primary | `x.y` `x?.y` `f(x)` `a[x]` `a?[x]` `x++` `x--` `x!` `new` `typeof` `default` `checked` `unchecked` `delegate` `stackalloc` | > | [§12.9](expressions.md#129-unary-operators) | Unary | `+` `-` `!x` `~` `^` `++x` `--x` `(T)x` `await x` | -> | §range-operator | Range | `..` | -> | [§12.10](expressions.md#1210-arithmetic-operators) | Multiplicative | `*` `/` `%` | -> | [§12.10](expressions.md#1210-arithmetic-operators) | Additive | `+` `-` | -> | [§12.11](expressions.md#1211-shift-operators) | Shift | `<<` `>>` | -> | [§12.12](expressions.md#1212-relational-and-type-testing-operators) | Relational and type-testing | `<` `>` `<=` `>=` `is` `as` | -> | [§12.12](expressions.md#1212-relational-and-type-testing-operators) | Equality | `==` `!=` | -> | [§12.13](expressions.md#1213-logical-operators) | Logical AND | `&` | -> | [§12.13](expressions.md#1213-logical-operators) | Logical XOR | `^` | -> | [§12.13](expressions.md#1213-logical-operators) | Logical OR | `\|` | -> | [§12.14](expressions.md#1214-conditional-logical-operators) | Conditional AND | `&&` | -> | [§12.14](expressions.md#1214-conditional-logical-operators) | Conditional OR | `\|\|` | -> | [§12.15](expressions.md#1215-the-null-coalescing-operator) and [§12.16](expressions.md#1216-the-throw-expression-operator) | Null coalescing and throw expression | `??` `throw x` | -> | [§12.18](expressions.md#1218-conditional-operator) | Conditional | `?:` | -> | [§12.21](expressions.md#1221-assignment-operators) and [§12.19](expressions.md#1219-anonymous-function-expressions) | Assignment and lambda expression | `=` `= ref` `*=` `/=` `%=` `+=` `-=` `<<=` `>>=` `&=` `^=` `\|=` `=>` `??=` | +> | [§12.10](expressions.md#1210-range-operator) | Range | `..` | +> | [§12.11](expressions.md#1211-arithmetic-operators) | Multiplicative | `*` `/` `%` | +> | [§12.11](expressions.md#1211-arithmetic-operators) | Additive | `+` `-` | +> | [§12.12](expressions.md#1212-shift-operators) | Shift | `<<` `>>` | +> | [§12.13](expressions.md#1213-relational-and-type-testing-operators) | Relational and type-testing | `<` `>` `<=` `>=` `is` `as` | +> | [§12.13](expressions.md#1213-relational-and-type-testing-operators) | Equality | `==` `!=` | +> | [§12.14](expressions.md#1214-logical-operators) | Logical AND | `&` | +> | [§12.14](expressions.md#1214-logical-operators) | Logical XOR | `^` | +> | [§12.14](expressions.md#1214-logical-operators) | Logical OR | `\|` | +> | [§12.15](expressions.md#1215-conditional-logical-operators) | Conditional AND | `&&` | +> | [§12.15](expressions.md#1215-conditional-logical-operators) | Conditional OR | `\|\|` | +> | [§12.16](expressions.md#1216-the-null-coalescing-operator) and [§12.17](expressions.md#1217-the-throw-expression-operator) | Null coalescing and throw expression | `??` `throw x` | +> | [§12.19](expressions.md#1219-conditional-operator) | Conditional | `?:` | +> | [§12.22](expressions.md#1222-assignment-operators) and [§12.20](expressions.md#1220-anonymous-function-expressions) | Assignment and lambda expression | `=` `= ref` `*=` `/=` `%=` `+=` `-=` `<<=` `>>=` `&=` `^=` `\|=` `=>` `??=` | > > *end note* @@ -187,9 +187,9 @@ The ***overloadable unary operators*** are: > `+ - !` (logical negation only) `~ ++ -- true false` -Only the operators listed above can be overloaded. In particular, it is not possible to overload the null-forgiving operator (postfix `!`, [§12.8.9](expressions.md#1289-null-forgiving-expressions)) or the unary hat operator (prefix `^`, (§hat-operator)). +Only the operators listed above can be overloaded. In particular, it is not possible to overload the null-forgiving operator (postfix `!`, [§12.8.9](expressions.md#1289-null-forgiving-expressions)) or the unary hat operator (prefix `^`, ([§12.9.6](expressions.md#1296-hat-operator))). -> *Note*: Although `true` and `false` are not used explicitly in expressions (and therefore are not included in the precedence table in [§12.4.2](expressions.md#1242-operator-precedence-and-associativity)), they are considered operators because they are invoked in several expression contexts: Boolean expressions ([§12.24](expressions.md#1224-boolean-expressions)) and expressions involving the conditional ([§12.18](expressions.md#1218-conditional-operator)) and conditional logical operators ([§12.14](expressions.md#1214-conditional-logical-operators)). *end note* +> *Note*: Although `true` and `false` are not used explicitly in expressions (and therefore are not included in the precedence table in [§12.4.2](expressions.md#1242-operator-precedence-and-associativity)), they are considered operators because they are invoked in several expression contexts: Boolean expressions ([§12.25](expressions.md#1225-boolean-expressions)) and expressions involving the conditional ([§12.19](expressions.md#1219-conditional-operator)) and conditional logical operators ([§12.15](expressions.md#1215-conditional-logical-operators)). *end note* The ***overloadable binary operators*** are: @@ -199,9 +199,9 @@ Only the operators listed above can be overloaded. In particular, it is not poss When a binary operator is overloaded, the corresponding compound assignment operator, if any, is also implicitly overloaded. -> *Example*: An overload of operator `*` is also an overload of operator `*=`. This is described further in [§12.21](expressions.md#1221-assignment-operators). *end example* +> *Example*: An overload of operator `*` is also an overload of operator `*=`. This is described further in [§12.22](expressions.md#1222-assignment-operators). *end example* -The assignment operator itself `(=)` cannot be overloaded. An assignment always performs a simple store of a value into a variable ([§12.21.2](expressions.md#12212-simple-assignment)). +The assignment operator itself `(=)` cannot be overloaded. An assignment always performs a simple store of a value into a variable ([§12.22.2](expressions.md#12222-simple-assignment)). Cast operations, such as `(T)x`, are overloaded by providing user-defined conversions ([§10.5](conversions.md#105-user-defined-conversions)). @@ -231,7 +231,7 @@ User-defined operator declarations cannot modify the syntax, precedence, or asso > *Note*: While it is possible for a user-defined operator to perform any computation it pleases, implementations that produce results other than those that are intuitively expected are strongly discouraged. For example, an implementation of operator `==` should compare the two operands for equality and return an appropriate `bool` result. *end note* -The descriptions of individual operators in [§12.9](expressions.md#129-unary-operators) through [§12.21](expressions.md#1221-assignment-operators) specify the predefined implementations of the operators and any additional rules that apply to each operator. The descriptions make use of the terms ***unary operator overload resolution***, ***binary operator overload resolution***, ***numeric promotion***, and lifted operator definitions of which are found in the following subclauses. +The descriptions of individual operators in [§12.9](expressions.md#129-unary-operators) through [§12.22](expressions.md#1222-assignment-operators) specify the predefined implementations of the operators and any additional rules that apply to each operator. The descriptions make use of the terms ***unary operator overload resolution***, ***binary operator overload resolution***, ***numeric promotion***, and lifted operator definitions of which are found in the following subclauses. ### 12.4.4 Unary operator overload resolution @@ -270,7 +270,7 @@ Given a type `T` and an operation `operator «op»(A)`, where «op» is an ove - the rules for implicit numeric conversions ([§10.2.3](conversions.md#1023-implicit-numeric-conversions)); - the rules for better conversion ([§12.6.4.7](expressions.md#12647-better-conversion-target)); and -- the available arithmetic ([§12.10](expressions.md#1210-arithmetic-operators)), relational ([§12.12](expressions.md#1212-relational-and-type-testing-operators)), and integral logical ([§12.13.2](expressions.md#12132-integer-logical-operators)) operators. +- the available arithmetic ([§12.11](expressions.md#1211-arithmetic-operators)), relational ([§12.13](expressions.md#1213-relational-and-type-testing-operators)), and integral logical ([§12.14.2](expressions.md#12142-integer-logical-operators)) operators. Numeric promotion consists of automatically performing certain implicit conversions of the operands of the predefined unary and binary numeric operators. Numeric promotion is not a distinct mechanism, but rather an effect of applying overload resolution to the predefined operators. Numeric promotion specifically does not affect evaluation of user-defined operators, although user-defined operators can be implemented to exhibit similar effects. @@ -348,7 +348,7 @@ In both of the above cases, a cast expression can be used to explicitly convert ***Lifted operators*** permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following: - For the unary operators `+`, `++`, `-`, `--`, `!` (logical negation), `^`, and `~`, a lifted form of an operator exists if the operand and result types are both non-nullable value types. The lifted form is constructed by adding a single `?` modifier to the operand and result types. The lifted operator produces a `null` value if the operand is `null`. Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result. -- For the binary operators `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `..`, `<<`, and `>>`, a lifted form of an operator exists if the operand and result types are all non-nullable value types. The lifted form is constructed by adding a single `?` modifier to each operand and result type. The lifted operator produces a `null` value if one or both operands are `null` (an exception being the `&` and `|` operators of the `bool?` type, as described in [§12.13.5](expressions.md#12135-nullable-boolean--and--operators)). Otherwise, the lifted operator unwraps the operands, applies the underlying operator, and wraps the result. +- For the binary operators `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `..`, `<<`, and `>>`, a lifted form of an operator exists if the operand and result types are all non-nullable value types. The lifted form is constructed by adding a single `?` modifier to each operand and result type. The lifted operator produces a `null` value if one or both operands are `null` (an exception being the `&` and `|` operators of the `bool?` type, as described in [§12.14.5](expressions.md#12145-nullable-boolean--and--operators)). Otherwise, the lifted operator unwraps the operands, applies the underlying operator, and wraps the result. - For the equality operators `==` and `!=`, a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is `bool`. The lifted form is constructed by adding a single `?` modifier to each operand type. The lifted operator considers two `null` values equal, and a `null` value unequal to any non-`null` value. If both operands are non-`null`, the lifted operator unwraps the operands and applies the underlying operator to produce the `bool` result. - For the relational operators `<`, `>`, `<=`, and `>=`, a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is `bool`. The lifted form is constructed by adding a single `?` modifier to each operand type. The lifted operator produces the value `false` if one or both operands are `null`. Otherwise, the lifted operator unwraps the operands and applies the underlying operator to produce the `bool` result. @@ -358,7 +358,7 @@ In both of the above cases, a cast expression can be used to explicitly convert A member lookup is the process whereby the meaning of a name in the context of a type is determined. A member lookup can occur as part of evaluating a *simple_name* ([§12.8.4](expressions.md#1284-simple-names)) or a *member_access* ([§12.8.7](expressions.md#1287-member-access)) in an expression. If the *simple_name* or *member_access* occurs as the *primary_expression* of an *invocation_expression* ([§12.8.10.2](expressions.md#128102-method-invocations)), the member is said to be *invoked*. -If a member is a method or event, or if it is a constant, field or property of either a delegate type ([§20](delegates.md#20-delegates)) or the type `dynamic` ([§8.2.4](types.md#824-the-dynamic-type)), then the member is said to be *invocable.* +If a member is a method or event, or if it is a constant, field or property of either a delegate type ([§21](delegates.md#21-delegates)) or the type `dynamic` ([§8.2.4](types.md#824-the-dynamic-type)), then the member is said to be *invocable.* Member lookup considers not only the name of a member but also the number of type parameters the member has and whether the member is accessible. For the purposes of member lookup, generic methods and nested generic types have the number of type parameters indicated in their respective declarations and all other members have zero type parameters. @@ -381,7 +381,7 @@ A member lookup of a name `N` with `K` type arguments in a type `T` is proces - Otherwise, if the set contains only methods, then this group of methods is the result of the lookup. - Otherwise, the lookup is ambiguous, and a binding-time error occurs. -For member lookups in types other than type parameters and interfaces, and member lookups in interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effect of the lookup rules is simply that derived members hide base members with the same name or signature. Such single-inheritance lookups are never ambiguous. The ambiguities that can possibly arise from member lookups in multiple-inheritance interfaces are described in [§18.4.6](interfaces.md#1846-interface-member-access). +For member lookups in types other than type parameters and interfaces, and member lookups in interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effect of the lookup rules is simply that derived members hide base members with the same name or signature. Such single-inheritance lookups are never ambiguous. The ambiguities that can possibly arise from member lookups in multiple-inheritance interfaces are described in [§19.4.6](interfaces.md#1946-interface-member-access). > *Note*: This phase only accounts for one kind of ambiguity. If the member lookup results in a method group, further uses of method group may fail due to ambiguity, for example as described in [§12.6.4.1](expressions.md#12641-general) and [§12.6.6.2](expressions.md#12662-invocations-on-boxed-instances). *end note* @@ -970,7 +970,7 @@ and the method group `M` being assigned to the delegate type `D` the task of t `M` -becomes compatible ([§20.2](delegates.md#202-delegate-declarations)) with `D`. +becomes compatible ([§21.2](delegates.md#212-delegate-declarations)) with `D`. Unlike the type inference algorithm for generic method calls, in this case, there are only argument *types*, no argument *expressions*. In particular, there are no anonymous functions and hence no need for multiple phases of inference. @@ -1113,7 +1113,7 @@ Given an implicit conversion `C₁` that converts from an expression `E` to a ty - `E` exactly matches `T₁` and `E` does not exactly match `T₂` ([§12.6.4.6](expressions.md#12646-exactly-matching-expression)) - `E` exactly matches both or neither of `T₁` and `T₂`, and `T₁` is a better conversion target than `T₂` ([§12.6.4.7](expressions.md#12647-better-conversion-target)) -- `E` is a method group ([§12.2](expressions.md#122-expression-classifications)), `T₁` is compatible ([§20.4](delegates.md#204-delegate-compatibility)) with the single best method from the method group for conversion `C₁`, and `T₂` is not compatible with the single best method from the method group for conversion `C₂` +- `E` is a method group ([§12.2](expressions.md#122-expression-classifications)), `T₁` is compatible ([§21.4](delegates.md#214-delegate-compatibility)) with the single best method from the method group for conversion `C₁`, and `T₂` is not compatible with the single best method from the method group for conversion `C₂` #### 12.6.4.6 Exactly matching expression @@ -1187,7 +1187,7 @@ Even though overload resolution of a dynamically bound operation takes place at - For a delegate invocation ([§12.8.10.4](expressions.md#128104-delegate-invocations)), the list is a single function member with the same parameter list as the *delegate_type* of the invocation - For a method invocation ([§12.8.10.2](expressions.md#128102-method-invocations)) on a type, or on a value whose static type is not dynamic, the set of accessible methods in the method group is known at compile-time. - For an object creation expression ([§12.8.17.2](expressions.md#128172-object-creation-expressions)) the set of accessible constructors in the type is known at compile-time. -- For an indexer access ([§12.8.12.3](expressions.md#128123-indexer-access)) the set of accessible indexers in the receiver is known at compile-time. +- For an indexer access ([§12.8.12.4](expressions.md#128124-indexer-access)) the set of accessible indexers in the receiver is known at compile-time. In these cases a limited compile-time check is performed on each member in the known set of function members, to see if it can be known for certain never to be invoked at run-time. For each function member `F` a modified parameter and argument list are constructed: @@ -1235,7 +1235,7 @@ The run-time processing of a function member invocation consists of the followin - If the type of `E` is a *value_type*, a boxing conversion ([§10.2.9](conversions.md#1029-boxing-conversions)) is performed to convert `E` to a *class_type*, and `E` is considered to be of that *class_type* in the following steps. If the *value_type* is an *enum_type*, the *class_type* is `System.Enum;` otherwise, it is `System.ValueType`. - The value of `E` is checked to be valid. If the value of `E` is null, a `System.NullReferenceException` is thrown and no further steps are executed. - The function member implementation to invoke is determined: - - If the binding-time type of `E` is an interface, the function member to invoke is the implementation of `M` provided by the run-time type of the instance referenced by `E`. This function member is determined by applying the interface mapping rules ([§18.6.5](interfaces.md#1865-interface-mapping)) to determine the implementation of `M` provided by the run-time type of the instance referenced by `E`. + - If the binding-time type of `E` is an interface, the function member to invoke is the implementation of `M` provided by the run-time type of the instance referenced by `E`. This function member is determined by applying the interface mapping rules ([§19.6.5](interfaces.md#1965-interface-mapping)) to determine the implementation of `M` provided by the run-time type of the instance referenced by `E`. - Otherwise, if `M` is a virtual function member, the function member to invoke is the implementation of `M` provided by the run-time type of the instance referenced by `E`. This function member is determined by applying the rules for determining the most derived implementation ([§15.6.4](classes.md#1564-virtual-methods)) of `M` with respect to the run-time type of the instance referenced by `E`. - Otherwise, `M` is a non-virtual function member, and the function member to invoke is `M` itself. - The function member implementation determined in the step above is invoked. The object referenced by `E` becomes the object referenced by this. @@ -1314,7 +1314,7 @@ primary_expression > *Note*: This grammar rule is not ANTLR-ready as it is part of a set of mutually left-recursive rules (`primary_expression`, `member_access`, `invocation_expression`, `element_access`, `post_increment_expression`, `post_decrement_expression`, `null_forgiving_expression`, `pointer_member_access` and `pointer_element_access`) which ANTLR does not handle. Standard techniques can be used to transform the grammar to remove the mutual left-recursion. This Standard does not do this as not all parsing strategies require it (e.g. an LALR parser would not) and doing so would obfuscate the structure and description. *end note* -*pointer_member_access* ([§23.6.3](unsafe-code.md#2363-pointer-member-access)) and *pointer_element_access* ([§23.6.4](unsafe-code.md#2364-pointer-element-access)) are only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*pointer_member_access* ([§24.6.3](unsafe-code.md#2463-pointer-member-access)) and *pointer_element_access* ([§24.6.4](unsafe-code.md#2464-pointer-element-access)) are only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). ### 12.8.2 Literals @@ -1560,7 +1560,7 @@ A *simple_name* is either of the form `I` or of the form `I`, - Otherwise, if the namespaces imported by the *using_namespace_directive*s of the namespace declaration contain exactly one type having name `I` and `e` type parameters, then the *simple_name* refers to that type constructed with the given type arguments. - Otherwise, if the namespaces imported by the *using_namespace_directive*s of the namespace declaration contain more than one type having name `I` and `e` type parameters, then the *simple_name* is ambiguous and a compile-time error occurs. > *Note*: This entire step is exactly parallel to the corresponding step in the processing of a *namespace_or_type_name* ([§7.8](basic-concepts.md#78-namespace-and-type-names)). *end note* -- Otherwise, if `e` is zero and `I` is the identifier `_`, the *simple_name* is a *simple discard*, which is a form of declaration expression ([§12.17](expressions.md#1217-declaration-expressions)). +- Otherwise, if `e` is zero and `I` is the identifier `_`, the *simple_name* is a *simple discard*, which is a form of declaration expression ([§12.18](expressions.md#1218-declaration-expressions)). - Otherwise, the *simple_name* is undefined and a compile-time error occurs. ### 12.8.5 Parenthesized expressions @@ -1605,7 +1605,7 @@ deconstruction_element A *tuple_expression* is classified as a tuple. -A *deconstruction_expression* `var (e1, ..., en)` is shorthand for the *tuple_expression* `(var e1, ..., var en)` and follows the same behavior. This applies recursively to any nested *deconstruction_tuple*s in the *deconstruction_expression*. Each identifier nested within a *deconstruction_expression* thus introduces a declaration expression ([§12.17](expressions.md#1217-declaration-expressions)). As a result, a *deconstruction_expression* can only occur on the left side of a simple assignment. +A *deconstruction_expression* `var (e1, ..., en)` is shorthand for the *tuple_expression* `(var e1, ..., var en)` and follows the same behavior. This applies recursively to any nested *deconstruction_tuple*s in the *deconstruction_expression*. Each identifier nested within a *deconstruction_expression* thus introduces a declaration expression ([§12.18](expressions.md#1218-declaration-expressions)). As a result, a *deconstruction_expression* can only occur on the left side of a simple assignment. > *Example*: > The following code declares three variables: a, b, and c. Each of which is an integer and is assigned its value from the tuple on the right hand side of the assignment. @@ -1647,7 +1647,7 @@ A tuple expression has a type if and only if each of its element expressions `Ei A tuple expression is evaluated by evaluating each of its element expressions in order from left to right. -A tuple value can be obtained from a tuple expression by converting it to a tuple type ([§10.2.13](conversions.md#10213-implicit-tuple-conversions)), by reclassifying it as a value ([§12.2.2](expressions.md#1222-values-of-expressions))) or by making it the target of a deconstructing assignment ([§12.21.2](expressions.md#12212-simple-assignment)). +A tuple value can be obtained from a tuple expression by converting it to a tuple type ([§10.2.13](conversions.md#10213-implicit-tuple-conversions)), by reclassifying it as a value ([§12.2.2](expressions.md#1222-values-of-expressions))) or by making it the target of a deconstructing assignment ([§12.22.2](expressions.md#12222-simple-assignment)). > *Example*: > @@ -1996,7 +1996,7 @@ The optional *argument_list* ([§12.6.2](expressions.md#1262-argument-lists)) pr The result of evaluating an *invocation_expression* is classified as follows: -- If the *invocation_expression* invokes a returns-no-value method ([§15.6.1](classes.md#1561-general)) or a returns-no-value delegate, the result is nothing. An expression that is classified as nothing is permitted only in the context of a *statement_expression* ([§13.7](statements.md#137-expression-statements)) or as the body of a *lambda_expression* ([§12.19](expressions.md#1219-anonymous-function-expressions)). Otherwise, a binding-time error occurs. +- If the *invocation_expression* invokes a returns-no-value method ([§15.6.1](classes.md#1561-general)) or a returns-no-value delegate, the result is nothing. An expression that is classified as nothing is permitted only in the context of a *statement_expression* ([§13.7](statements.md#137-expression-statements)) or as the body of a *lambda_expression* ([§12.20](expressions.md#1220-anonymous-function-expressions)). Otherwise, a binding-time error occurs. - Otherwise, if the *invocation_expression* invokes a returns-by-ref method ([§15.6.1](classes.md#1561-general)) or a returns-by-ref delegate, the result is a variable with an associated type of the return type of the method or delegate. If the invocation is of an instance method, and the receiver is of a class type `T`, the associated type is picked from the first declaration or override of the method found when starting with `T` and searching through its base classes. - Otherwise, the *invocation_expression* invokes a returns-by-value method ([§15.6.1](classes.md#1561-general)) or returns-by-value delegate, and the result is a value, with an associated type of the return type of the method or delegate. If the invocation is of an instance method, and the receiver is of a class type `T`, the associated type is picked from the first declaration or override of the method found when starting with `T` and searching through its base classes. @@ -2169,13 +2169,13 @@ The run-time processing of a delegate invocation of the form `D(A)`, where `D` - The value of `D` is checked to be valid. If the value of `D` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. - Otherwise, `D` is a reference to a delegate instance. Function member invocations ([§12.6.6](expressions.md#1266-function-member-invocation)) are performed on each of the callable entities in the invocation list of the delegate. For callable entities consisting of an instance and instance method, the instance for the invocation is the instance contained in the callable entity. -See [§20.6](delegates.md#206-delegate-invocation) for details of multiple invocation lists without parameters. +See [§21.6](delegates.md#216-delegate-invocation) for details of multiple invocation lists without parameters. ### 12.8.11 Null Conditional Invocation Expression A *null_conditional_invocation_expression* is syntactically either a *null_conditional_member_access* ([§12.8.8](expressions.md#1288-null-conditional-member-access)) or *null_conditional_element_access* ([§12.8.13](expressions.md#12813-null-conditional-element-access)) where the final *dependent_access* is an invocation expression ([§12.8.10](expressions.md#12810-invocation-expressions)). -A *null_conditional_invocation_expression* occurs within the context of a *statement_expression* ([§13.7](statements.md#137-expression-statements)), *anonymous_function_body* ([§12.19.1](expressions.md#12191-general)), or *method_body* ([§15.6.1](classes.md#1561-general)). +A *null_conditional_invocation_expression* occurs within the context of a *statement_expression* ([§13.7](statements.md#137-expression-statements)), *anonymous_function_body* ([§12.20.1](expressions.md#12201-general)), or *method_body* ([§15.6.1](classes.md#1561-general)). Unlike the syntactically equivalent *null_conditional_member_access* or *null_conditional_element_access*, a *null_conditional_invocation_expression* may be classified as nothing. @@ -2232,7 +2232,7 @@ element_access ; ``` -When recognising a *primary_expression* if both the *element_access* and *pointer_element_access* ([§23.6.4](unsafe-code.md#2364-pointer-element-access)) alternatives are applicable then the latter shall be chosen if the embedded *primary_expression* is of pointer type ([§23.3](unsafe-code.md#233-pointer-types)). +When recognising a *primary_expression* if both the *element_access* and *pointer_element_access* ([§24.6.4](unsafe-code.md#2464-pointer-element-access)) alternatives are applicable then the latter shall be chosen if the embedded *primary_expression* is of pointer type ([§24.3](unsafe-code.md#243-pointer-types)). The *primary_expression* of an *element_access* shall not be an *array_creation_expression* unless it includes an *array_initializer*, or a *stackalloc_expression* unless it includes a *stackalloc_initializer*. @@ -2274,12 +2274,12 @@ In this case the compile-time type of the *element_access* depends on the compil If the *primary_expression* of an *element_access* is: - a value of an array type, the *element_access* is an array access ([§12.8.12.2](expressions.md#128122-array-access)); -- a value of `string` type, the *element_access* is a string access (§string-access); -- otherwise, the *primary_expression* shall be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the *element_access* is an indexer access ([§12.8.12.3](expressions.md#128123-indexer-access)). +- a value of `string` type, the *element_access* is a string access ([§12.8.12.3](expressions.md#128123-string-access)); +- otherwise, the *primary_expression* shall be a variable or value of a class, struct, or interface type that has one or more indexer members, in which case the *element_access* is an indexer access ([§12.8.12.4](expressions.md#128124-indexer-access)). #### 12.8.12.2 Array access -For an array access the *argument_list* shall not contain named arguments or by-reference arguments (§15.6.2.3). +For an array access the *argument_list* shall not contain named arguments or by-reference arguments ([§15.6.2.3](classes.md#15623-by-reference-parameters)). The number of expressions in the *argument_list* shall be the same as the rank of the *array_type*, and each expression shall be: @@ -2297,24 +2297,24 @@ The run-time processing of an array access of the form `P[A]`, where `P` is a *p - The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. - If the preceding steps have produced a single index value of type `Range` then: - Let *L* be the length of the array referenced by `P`. - - `A` is checked to be valid with respect to *L* (§24.3). If it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. - - The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` (§24.3). + - `A` is checked to be valid with respect to *L* ([§18.3](ranges.md#183-the-range-type)). If it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. + - The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` ([§18.3](ranges.md#183-the-range-type)). - The result of the array access is an array containing a shallow copy of the *N* elements of `P` starting at index *S*. If *N* is zero the array has zero elements. -> > > *Note:* Both *S* and *N* may be zero ($24.3). Indexing an empty array is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty array. The definition also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty array returned. *end note* +> > > *Note:* Both *S* and *N* may be zero ($24.3). Indexing an empty array is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty array. The definition also allows *S* to be *L*, the past-end index ([§18.1](ranges.md#181-general)), in which case *N* will be zero and an empty array returned. *end note* -> > > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses (§12.8.12.3) which may, but need not, support assignment to a range of indices specified by a `Range` value. *end note* +> > > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses ([§12.8.12.4](expressions.md#128124-indexer-access)) which may, but need not, support assignment to a range of indices specified by a `Range` value. *end note* - Otherwise: - - The result of evaluating the array access is a variable reference (§9.5) of the element type of the array. + - The result of evaluating the array access is a variable reference ([§9.5](variables.md#95-variable-references)) of the element type of the array. - The value of each expression in the *argument_list* is checked against the actual bounds of each dimension of the array instance referenced by `P`. If one or more values are out of range, a `System.IndexOutOfRangeException` is thrown and no further steps are executed. - The variable reference of the array element given by the index expressions is computed, and this becomes the result of the array access. -#### §string-access String access +#### 12.8.12.3 String access -For a string access the *argument_list* of the *element_access* shall contain a single unnamed value argument (§15.6.2.2) which shall be: +For a string access the *argument_list* of the *element_access* shall contain a single unnamed value argument ([§15.6.2.2](classes.md#15622-value-parameters)) which shall be: - of type `int`, `Index` or `Range`; or - implicitly convertible to one or more of the above types. @@ -2329,18 +2329,18 @@ The run-time processing of a string access of the form `P[A]`, where `P` is a *p - If the preceding steps have produced an index value of type `Range` then: - The result of evaluating the string access is a value of `string` type. - Let *L* be the length of the string referenced by `P`. - - `A` is checked to be valid with respect to *L* (§24.3), if it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. - - The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` (§24.3). + - `A` is checked to be valid with respect to *L* ([§18.3](ranges.md#183-the-range-type)), if it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. + - The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` ([§18.3](ranges.md#183-the-range-type)). - The result of the string access is a string formed by copying the *N* characters of `P` starting from *S*, if *N* is zero the string is empty. -> > > *Note:* Both *S* and *N* may be zero (§24.3). Indexing an empty string is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty string. The defintion also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty string returned. *end note* +> > > *Note:* Both *S* and *N* may be zero ([§18.3](ranges.md#183-the-range-type)). Indexing an empty string is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty string. The defintion also allows *S* to be *L*, the past-end index ([§18.1](ranges.md#181-general)), in which case *N* will be zero and an empty string returned. *end note* - Otherwise: - The result of evaluating the string access is a value of `char` type. - The value of the converted index expression is checked against the actual bounds of the string instance referenced by `P`. If the value is out of range, a `System.IndexOutOfRangeException` is thrown and no further steps are executed. - The value of character at the offset of the converted index expression with the string `P` becomes the result of the string access. -#### 12.8.12.3 Indexer access +#### 12.8.12.4 Indexer access For an indexer access, the *primary_expression* of the *element_access* shall be a variable or value of a class, struct, or interface type, and this type shall implement one or more indexers that are applicable with respect to the *argument_list* of the *element_access*. The *argument_list* shall not contain `out` or `ref` arguments. @@ -2362,7 +2362,7 @@ The runtime processing of the indexer access consists of the following steps: - The target *primary_expression* `P` is evaluated. - The index expressions of the *argument_list* `A` are evaluated in order, from left to right. - Using the best indexer determined at binding-time: - - If the indexer access is the target of an assignment, the set accessor or ref get accessor is invoked to assign a new value ([§12.21.2](expressions.md#12212-simple-assignment)). + - If the indexer access is the target of an assignment, the set accessor or ref get accessor is invoked to assign a new value ([§12.22.2](expressions.md#12222-simple-assignment)). - In all other cases, the get accessor or ref get accessor is invoked to obtain the current value ([§12.2.2](expressions.md#1222-values-of-expressions)). ### 12.8.13 Null Conditional Element Access @@ -2517,7 +2517,7 @@ The run-time processing of a postfix increment or decrement operation of the for - The value returned by the operator is converted to the type of `x` and the set accessor of `x` is invoked with this value as its value argument. - The saved value of `x` becomes the result of the operation. -The `++` and `--` operators also support prefix notation ([§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators)). The result of `x++` or `x--` is the value of `x` *before* the operation, whereas the result of `++x` or `--x` is the value of `x` *after* the operation. In either case, `x` itself has the same value after the operation. +The `++` and `--` operators also support prefix notation ([§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators)). The result of `x++` or `x--` is the value of `x` *before* the operation, whereas the result of `++x` or `--x` is the value of `x` *after* the operation. In either case, `x` itself has the same value after the operation. An operator `++` or operator `--` implementation can be invoked using either postfix or prefix notation. It is not possible to have separate operator implementations for the two notations. @@ -2625,9 +2625,9 @@ An object initializer consists of a sequence of member initializers, enclosed by Each *initializer_target* is followed by an equals sign and either an expression, an object initializer or a collection initializer. It is not possible for expressions within the object initializer to refer to the newly created object it is initializing. -In the *argument_list* of an *initializer_target* there is no implicit support for arguments of type `Index` (§24.4.2) or `Range` (§24.4.3). +In the *argument_list* of an *initializer_target* there is no implicit support for arguments of type `Index` ([§18.4.2](ranges.md#1842-implicit-index-support)) or `Range` ([§18.4.3](ranges.md#1843-implicit-range-support)). -A member initializer that specifies an expression after the equals sign is processed in the same way as an assignment ([§12.21.2](expressions.md#12212-simple-assignment)) to the target. +A member initializer that specifies an expression after the equals sign is processed in the same way as an assignment ([§12.22.2](expressions.md#12222-simple-assignment)) to the target. A member initializer that specifies an object initializer after the equals sign is a ***nested object initializer***, i.e., an initialization of an embedded object. Instead of assigning a new value to the field or property, the assignments in the nested object initializer are treated as assignments to members of the field or property. Nested object initializers cannot be applied to properties with a value type, or to read-only fields with a value type. @@ -2765,7 +2765,7 @@ expression_list ; ``` -A collection initializer consists of a sequence of element initializers, enclosed by `{` and `}` tokens and separated by commas. Each element initializer specifies an element to be added to the collection object being initialized, and consists of a list of expressions enclosed by `{` and `}` tokens and separated by commas. A single-expression element initializer can be written without braces, but cannot then be an assignment expression, to avoid ambiguity with member initializers. The *non_assignment_expression* production is defined in [§12.22](expressions.md#1222-expression). +A collection initializer consists of a sequence of element initializers, enclosed by `{` and `}` tokens and separated by commas. Each element initializer specifies an element to be added to the collection object being initialized, and consists of a list of expressions enclosed by `{` and `}` tokens and separated by commas. A single-expression element initializer can be written without braces, but cannot then be an assignment expression, to avoid ambiguity with member initializers. The *non_assignment_expression* production is defined in [§12.23](expressions.md#1223-expression). > *Example*: > The following is an example of an object creation expression that includes a collection initializer: @@ -2938,7 +2938,7 @@ An array creation expression of the first form allocates an array instance of th Each expression in the expression list shall be of type `int`, `uint`, `long`, or `ulong`, or implicitly convertible to one or more of these types. The value of each expression determines the length of the corresponding dimension in the newly allocated array instance. Since the length of an array dimension shall be nonnegative, it is a compile-time error to have a constant expression with a negative value, in the expression list. -Except in an unsafe context ([§23.2](unsafe-code.md#232-unsafe-contexts)), the layout of arrays is unspecified. +Except in an unsafe context ([§24.2](unsafe-code.md#242-unsafe-contexts)), the layout of arrays is unspecified. If an array creation expression of the first form includes an array initializer, each expression in the expression list shall be a constant and the rank and dimension lengths specified by the expression list shall match those of the array initializer. @@ -3068,7 +3068,7 @@ The binding-time processing of a *delegate_creation_expression* of the form new - If `E` is a method group, the delegate creation expression is processed in the same way as a method group conversion ([§10.8](conversions.md#108-method-group-conversions)) from `E` to `D`. - If `E` is an anonymous function, the delegate creation expression is processed in the same way as an anonymous function conversion ([§10.7](conversions.md#107-anonymous-function-conversions)) from `E` to `D`. -- If `E` is a value, `E` shall be compatible ([§20.2](delegates.md#202-delegate-declarations)) with `D`, and the result is a reference to a newly created delegate with a single-entry invocation list that invokes  `E`. +- If `E` is a value, `E` shall be compatible ([§21.2](delegates.md#212-delegate-declarations)) with `D`, and the result is a reference to a newly created delegate with a single-entry invocation list that invokes  `E`. The run-time processing of a *delegate_creation_expression* of the form new `D(E)`, where `D` is a *delegate_type* and `E` is an *expression*, consists of the following steps: @@ -3246,7 +3246,7 @@ For certain predefined types the `sizeof` operator yields a constant `int` value |`sizeof(bool)` | 1 | |`sizeof(decimal)` | 16 | -For an enum type `T`, the result of the expression `sizeof(T)` is a constant value equal to the size of its underlying type, as given above. For all other operand types, the `sizeof` operator is specified in [§23.6.9](unsafe-code.md#2369-the-sizeof-operator). +For an enum type `T`, the result of the expression `sizeof(T)` is a constant value equal to the size of its underlying type, as given above. For all other operand types, the `sizeof` operator is specified in [§24.6.9](unsafe-code.md#2469-the-sizeof-operator). ### 12.8.20 The checked and unchecked operators @@ -3268,19 +3268,19 @@ The overflow checking context can also be controlled through the `checked` and ` The following operations are affected by the overflow checking context established by the checked and unchecked operators and statements: -- The predefined `++` and `--` operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators) and [§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators)), when the operand is of an integral or enum type. +- The predefined `++` and `--` operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators) and [§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators)), when the operand is of an integral or enum type. - The predefined `-` unary operator ([§12.9.3](expressions.md#1293-unary-minus-operator)), when the operand is of an integral type. -- The predefined `+`, `-`, `*`, and `/` binary operators ([§12.10](expressions.md#1210-arithmetic-operators)), when both operands are of integral or enum types. +- The predefined `+`, `-`, `*`, and `/` binary operators ([§12.11](expressions.md#1211-arithmetic-operators)), when both operands are of integral or enum types. - Explicit numeric conversions ([§10.3.2](conversions.md#1032-explicit-numeric-conversions)) from one integral or enum type to another integral or enum type, or from `float` or `double` to an integral or enum type. When one of the above operations produces a result that is too large to represent in the destination type, the context in which the operation is performed controls the resulting behavior: -- In a `checked` context, if the operation is a constant expression ([§12.23](expressions.md#1223-constant-expressions)), a compile-time error occurs. Otherwise, when the operation is performed at run-time, a `System.OverflowException` is thrown. +- In a `checked` context, if the operation is a constant expression ([§12.24](expressions.md#1224-constant-expressions)), a compile-time error occurs. Otherwise, when the operation is performed at run-time, a `System.OverflowException` is thrown. - In an `unchecked` context, the result is truncated by discarding any high-order bits that do not fit in the destination type. -For non-constant expressions ([§12.23](expressions.md#1223-constant-expressions)) (expressions that are evaluated at run-time) that are not enclosed by any `checked` or `unchecked` operators or statements, the default overflow checking context is unchecked, unless external factors (such as compiler switches and execution environment configuration) call for checked evaluation. +For non-constant expressions ([§12.24](expressions.md#1224-constant-expressions)) (expressions that are evaluated at run-time) that are not enclosed by any `checked` or `unchecked` operators or statements, the default overflow checking context is unchecked, unless external factors (such as compiler switches and execution environment configuration) call for checked evaluation. -For constant expressions ([§12.23](expressions.md#1223-constant-expressions)) (expressions that can be fully evaluated at compile-time), the default overflow checking context is always checked. Unless a constant expression is explicitly placed in an `unchecked` context, overflows that occur during the compile-time evaluation of the expression always cause compile-time errors. +For constant expressions ([§12.24](expressions.md#1224-constant-expressions)) (expressions that can be fully evaluated at compile-time), the default overflow checking context is always checked. Unless a constant expression is explicitly placed in an `unchecked` context, overflows that occur during the compile-time evaluation of the expression always cause compile-time errors. The body of an anonymous function is not affected by `checked` or `unchecked` contexts in which the anonymous function occurs. @@ -3386,7 +3386,7 @@ A *default_literal* represents a default value ([§9.3](variables.md#93-default- The result of a *default_value_expression* is the default ([§9.3](variables.md#93-default-values)) of the explicit type in an *explicitly_typed_default*, or the target type of the conversion for a *default_value_expression*. -A *default_value_expression* is a constant expression ([§12.23](expressions.md#1223-constant-expressions)) if the type is one of: +A *default_value_expression* is a constant expression ([§12.24](expressions.md#1224-constant-expressions)) if the type is one of: - a reference type - a type parameter that is known to be a reference type ([§8.2](types.md#82-reference-types)); @@ -3432,7 +3432,7 @@ When a *stackalloc_initializer* is present: Each *stackalloc_element_initializer* shall have an implicit conversion to *unmanaged_type* ([§10.2](conversions.md#102-implicit-conversions)). The *stackalloc_element_initializer*s initialize elements in the allocated memory in increasing order, starting with the element at index zero. In the absence of a *stackalloc_initializer*, the content of the newly allocated memory is undefined. -If a *stackalloc_expression* occurs directly as the initializing expression of a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)), where the *local_variable_type* is either a pointer type ([§23.3](unsafe-code.md#233-pointer-types)) or inferred (`var`), then the result of the *stackalloc_expression* is a pointer of type `T*` ([§23.9](unsafe-code.md#239-stack-allocation)). In this case the *stackalloc_expression* must appear in unsafe code. Otherwise the result of a *stackalloc_expression* is an instance of type `Span`, where `T` is the *unmanaged_type*: +If a *stackalloc_expression* occurs directly as the initializing expression of a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)), where the *local_variable_type* is either a pointer type ([§24.3](unsafe-code.md#243-pointer-types)) or inferred (`var`), then the result of the *stackalloc_expression* is a pointer of type `T*` ([§24.9](unsafe-code.md#249-stack-allocation)). In this case the *stackalloc_expression* must appear in unsafe code. Otherwise the result of a *stackalloc_expression* is an instance of type `Span`, where `T` is the *unmanaged_type*: - `Span` ([§C.3](standard-library.md#c3-standard-library-types-not-defined-in-isoiec-23271)) is a ref struct type ([§16.2.3](structs.md#1623-ref-modifier)), which presents a block of memory, here the block allocated by the *stackalloc_expression*, as an indexable collection of typed (`T`) items. - The result’s `Length` property returns the number of items allocated. @@ -3565,7 +3565,7 @@ These are the same transformations applied in [§6.4.3](lexical-structure.md#643 ### 12.8.24 Anonymous method expressions -An *anonymous_method_expression* is one of two ways of defining an anonymous function. These are further described in [§12.19](expressions.md#1219-anonymous-function-expressions). +An *anonymous_method_expression* is one of two ways of defining an anonymous function. These are further described in [§12.20](expressions.md#1220-anonymous-function-expressions). ## 12.9 Unary operators @@ -3592,12 +3592,12 @@ unary_expression ; ``` -*pointer_indirection_expression* ([§23.6.2](unsafe-code.md#2362-pointer-indirection)) and *addressof_expression* ([§23.6.5](unsafe-code.md#2365-the-address-of-operator)) are available only in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*pointer_indirection_expression* ([§24.6.2](unsafe-code.md#2462-pointer-indirection)) and *addressof_expression* ([§24.6.5](unsafe-code.md#2465-the-address-of-operator)) are available only in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). If the operand of a *unary_expression* has the compile-time type `dynamic`, it is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). In this case: - the compile-time type of the *unary_expression* is: - - `Index` for the `^` hat operator (§hat-operator) + - `Index` for the `^` hat operator ([§12.9.6](expressions.md#1296-hat-operator)) - `dynamic` for all other unary operators; and - the resolution described below will take place at run-time using the run-time type of the operand. @@ -3690,25 +3690,25 @@ The result of evaluating `~x`, where `X` is an expression of an enumeration ty Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined bitwise complement operators defined above are also predefined. -### §hat-operator Hat operator +### 12.9.6 Hat operator -The unary `^` operator is called the *hat* operator. The hat operator is not overloadable (§12.4.3) and there is a single predefined hat operator: +The unary `^` operator is called the *hat* operator. The hat operator is not overloadable ([§12.4.3](expressions.md#1243-operator-overloading)) and there is a single predefined hat operator: ```csharp Index operator ^(int x); ``` -The result of an operation of the form `^x` is a from-end `Index` (§24.2) value equivalent to the result of the expression: +The result of an operation of the form `^x` is a from-end `Index` ([§18.2](ranges.md#182-the-index-type)) value equivalent to the result of the expression: ```csharp new Index(x, true) ``` -As with the other *unary_expression*s the operand may have a compile-time type of `dynamic` (§12.9.1) and be dynamically bound (§12.3.3). The compile-time type of the result is always `Index`. +As with the other *unary_expression*s the operand may have a compile-time type of `dynamic` ([§12.9.1](expressions.md#1291-general)) and be dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). The compile-time type of the result is always `Index`. A lifted ([§12.4.8](expressions.md#1248-lifted-operators)) form of the hat operator is also predefined. -### 12.9.6 Prefix increment and decrement operators +### 12.9.7 Prefix increment and decrement operators ```ANTLR pre_increment_expression @@ -3747,7 +3747,7 @@ An operator `++` or operator `--` implementation can be invoked using either p Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined prefix increment and decrement operators defined above are also predefined. -### 12.9.7 Cast expressions +### 12.9.8 Cast expressions A *cast_expression* is used to convert explicitly an expression to a given type. @@ -3776,9 +3776,9 @@ The term “correct grammar” above means only that the sequence of tokens shal > *Note*: From the disambiguation rule, it follows that, if `x` and `y` are identifiers, `(x)y`, `(x)(y)`, and `(x)(-y)` are *cast_expression*s, but `(x)-y` is not, even if `x` identifies a type. However, if `x` is a keyword that identifies a predefined type (such as `int`), then all four forms are *cast_expression*s (because such a keyword could not possibly be an expression by itself). *end note* -### 12.9.8 Await expressions +### 12.9.9 Await expressions -#### 12.9.8.1 General +#### 12.9.9.1 General The `await` operator is used to suspend evaluation of the enclosing async function until the asynchronous operation represented by the operand has completed. @@ -3801,7 +3801,7 @@ Inside an async function, `await` shall not be used as an *available_identifier* The operand of an *await_expression* is called the ***task***. It represents an asynchronous operation that might or might not be complete at the time the *await_expression* is evaluated. The purpose of the `await` operator is to suspend execution of the enclosing async function until the awaited task is complete, and then obtain its outcome. -#### 12.9.8.2 Awaitable expressions +#### 12.9.9.2 Awaitable expressions The task of an *await_expression* is required to be ***awaitable***. An expression `t` is awaitable if one of the following holds: @@ -3819,11 +3819,11 @@ The purpose of the `INotifyCompletion.OnCompleted` method is to sign up a “con The purpose of the `GetResult` method is to obtain the outcome of the task once it is complete. This outcome may be successful completion, possibly with a result value, or it may be an exception which is thrown by the `GetResult` method. -#### 12.9.8.3 Classification of await expressions +#### 12.9.9.3 Classification of await expressions The expression `await t` is classified the same way as the expression `(t).GetAwaiter().GetResult()`. Thus, if the return type of `GetResult` is `void`, the *await_expression* is classified as nothing. If it has a non-`void` return type `T`, the *await_expression* is classified as a value of type `T`. -#### 12.9.8.4 Run-time evaluation of await expressions +#### 12.9.9.4 Run-time evaluation of await expressions At run-time, the expression `await t` is evaluated as follows: @@ -3839,7 +3839,7 @@ At run-time, the expression `await t` is evaluated as follows: An awaiter’s implementation of the interface methods `INotifyCompletion.OnCompleted` and `ICriticalNotifyCompletion.UnsafeOnCompleted` should cause the delegate `r` to be invoked at most once. Otherwise, the behavior of the enclosing async function is undefined. -## §range-operator Range operator +## 12.10 Range operator The `..` operator is called the *range* operator. @@ -3856,14 +3856,14 @@ The predefined range operator is: Range operator ..(Index x, Index y); ``` -The range operator is not overloadable (§12.4.3). +The range operator is not overloadable ([§12.4.3](expressions.md#1243-operator-overloading)). All range expressions are treated as having the form `x..y`, where: - `x` is the left operand if present, otherwise the expression `0`; and - `y` is the right operand if present, otherwise the expression `^0`. -The result of the operation is a `Range` (§24.3) value equivalent to the result of the expression: +The result of the operation is a `Range` ([§18.3](ranges.md#183-the-range-type)) value equivalent to the result of the expression: ```csharp new Range(x, y) @@ -3873,11 +3873,11 @@ If either or both operands in a range expression have the compile-time type `dyn A lifted ([§12.4.8](expressions.md#1248-lifted-operators)) form of the range operator is also predefined. -The range operator is non-associative (§12.4.2). +The range operator is non-associative ([§12.4.2](expressions.md#1242-operator-precedence-and-associativity)). -## 12.10 Arithmetic operators +## 12.11 Arithmetic operators -### 12.10.1 General +### 12.11.1 General The `*`, `/`, `%`, `+`, and `-` operators are called the arithmetic operators. @@ -3898,7 +3898,7 @@ additive_expression If an operand of an arithmetic operator has the compile-time type `dynamic`, then the expression is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). In this case, the compile-time type of the expression is `dynamic`, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type `dynamic`. -### 12.10.2 Multiplication operator +### 12.11.2 Multiplication operator For an operation of the form `x * y`, binary operator overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. @@ -3933,7 +3933,7 @@ The predefined multiplication operators are listed below. The operators all comp | **`-∞`** | `-∞` | `+∞` | `NaN` | `NaN` | `-∞` | `+∞` | `NaN` | | **`NaN`** | `NaN` | `NaN` | `NaN` | `NaN` | `NaN` | `NaN` | `NaN` | - (Except where otherwise noted, in the floating-point tables in [§12.10.2](expressions.md#12102-multiplication-operator)–[§12.10.6](expressions.md#12106-subtraction-operator) the use of “`+`” means the value is positive; the use of “`-`” means the value is negative; and the lack of a sign means the value may be positive or negative or has no sign (NaN).) + (Except where otherwise noted, in the floating-point tables in [§12.11.2](expressions.md#12112-multiplication-operator)–[§12.11.6](expressions.md#12116-subtraction-operator) the use of “`+`” means the value is positive; the use of “`-`” means the value is negative; and the lack of a sign means the value may be positive or negative or has no sign (NaN).) - Decimal multiplication: ```csharp @@ -3945,7 +3945,7 @@ The predefined multiplication operators are listed below. The operators all comp Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined multiplication operators defined above are also predefined. -### 12.10.3 Division operator +### 12.11.3 Division operator For an operation of the form `x / y`, binary operator overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. @@ -3996,7 +3996,7 @@ The predefined division operators are listed below. The operators all compute th Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined division operators defined above are also predefined. -### 12.10.4 Remainder operator +### 12.11.4 Remainder operator For an operation of the form `x % y`, binary operator overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. @@ -4046,7 +4046,7 @@ The predefined remainder operators are listed below. The operators all compute t Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined remainder operators defined above are also predefined. -### 12.10.5 Addition operator +### 12.11.5 Addition operator For an operation of the form `x + y`, binary operator overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. @@ -4144,11 +4144,11 @@ The predefined addition operators are listed below. For numeric and enumeration If the first operand is `null`, the result of the operation is the value of the second operand (even if that is also `null`). Otherwise, if the second operand is `null`, then the result of the operation is the value of the first operand. Otherwise, the result of the operation is a new delegate instance whose invocation list consists of the elements in the invocation list of the first operand, followed by the elements in the invocation list of the second operand. That is, the invocation list of the resulting delegate is the concatenation of the invocation lists of the two operands. - > *Note*: For examples of delegate combination, see [§12.10.6](expressions.md#12106-subtraction-operator) and [§20.6](delegates.md#206-delegate-invocation). Since `System.Delegate` is not a delegate type, operator + is not defined for it. *end note* + > *Note*: For examples of delegate combination, see [§12.11.6](expressions.md#12116-subtraction-operator) and [§21.6](delegates.md#216-delegate-invocation). Since `System.Delegate` is not a delegate type, operator + is not defined for it. *end note* Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined addition operators defined above are also predefined. -### 12.10.6 Subtraction operator +### 12.11.6 Subtraction operator For an operation of the form `x – y`, binary operator overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. @@ -4216,8 +4216,8 @@ The predefined subtraction operators are listed below. The operators all subtrac The semantics are as follows: - If the first operand is `null`, the result of the operation is `null`. - Otherwise, if the second operand is `null`, then the result of the operation is the value of the first operand. - - Otherwise, both operands represent non-empty invocation lists ([§20.2](delegates.md#202-delegate-declarations)). - - If the lists compare equal, as determined by the delegate equality operator ([§12.12.9](expressions.md#12129-delegate-equality-operators)), the result of the operation is `null`. + - Otherwise, both operands represent non-empty invocation lists ([§21.2](delegates.md#212-delegate-declarations)). + - If the lists compare equal, as determined by the delegate equality operator ([§12.13.9](expressions.md#12139-delegate-equality-operators)), the result of the operation is `null`. - Otherwise, the result of the operation is a new invocation list consisting of the first operand’s list with the second operand’s entries removed from it, provided the second operand’s list is a sublist of the first’s. (To determine sublist equality, corresponding entries are compared as for the delegate equality operator.) If the second operand’s list matches multiple sublists of contiguous entries in the first operand’s list, the last matching sublist of contiguous entries is removed. - Otherwise, the result of the operation is the value of the left operand. @@ -4259,7 +4259,7 @@ The predefined subtraction operators are listed below. The operators all subtrac Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined subtraction operators defined above are also predefined. -## 12.11 Shift operators +## 12.12 Shift operators The `<<` and `>>` operators are used to perform bit-shifting operations. @@ -4321,9 +4321,9 @@ When the left operand of the `>>` operator is of a signed integral type, the op Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined shift operators defined above are also predefined. -## 12.12 Relational and type-testing operators +## 12.13 Relational and type-testing operators -### 12.12.1 General +### 12.13.1 General The `==`, `!=`, `<`, `>`, `<=`, `>=`, `is`, and `as` operators are called the relational and type-testing operators. @@ -4348,7 +4348,7 @@ equality_expression > *Note*: Lookup for the right operand of the `is` operator must first test as a *type*, then as an *expression* which may span multiple tokens. In the case where the operand is an *expression*, the pattern expression must have precedence at least as high as *shift_expression*. *end note* -The `is` operator is described in [§12.12.12](expressions.md#121212-the-is-operator) and the `as` operator is described in [§12.12.13](expressions.md#121213-the-as-operator). +The `is` operator is described in [§12.13.12](expressions.md#121312-the-is-operator) and the `as` operator is described in [§12.13.13](expressions.md#121313-the-as-operator). The `==`, `!=`, `<`, `>`, `<=` and `>=` operators are ***comparison operators***. @@ -4370,7 +4370,7 @@ The predefined comparison operators are described in the following subclauses. A |`x <= y` | `true` if `x` is less than or equal to `y`, `false` otherwise | |`x >= y` | `true` if `x` is greater than or equal to `y`, `false` otherwise | -### 12.12.2 Integer comparison operators +### 12.13.2 Integer comparison operators The predefined integer comparison operators are: @@ -4410,7 +4410,7 @@ Each of these operators compares the numeric values of the two integer operands Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined integer comparison operators defined above are also predefined. -### 12.12.3 Floating-point comparison operators +### 12.13.3 Floating-point comparison operators The predefined floating-point comparison operators are: @@ -4454,7 +4454,7 @@ where `min` and `max` are the smallest and largest positive finite values that c Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined floating-point comparison operators defined above are also predefined. -### 12.12.4 Decimal comparison operators +### 12.13.4 Decimal comparison operators The predefined decimal comparison operators are: @@ -4471,7 +4471,7 @@ Each of these operators compares the numeric values of the two decimal operands Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined decimal comparison operators defined above are also predefined. -### 12.12.5 Boolean equality operators +### 12.13.5 Boolean equality operators The predefined Boolean equality operators are: @@ -4486,7 +4486,7 @@ The result of `!=` is `false` if both `x` and `y` are `true` or if both `x` and Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined Boolean equality operators defined above are also predefined. -### 12.12.6 Enumeration comparison operators +### 12.13.6 Enumeration comparison operators Every enumeration type implicitly provides the following predefined comparison operators @@ -4504,7 +4504,7 @@ The result of evaluating `x «op» y`, where x and y are expressions of an enu Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined enumeration comparison operators defined above are also predefined. -### 12.12.7 Reference type equality operators +### 12.13.7 Reference type equality operators Every class type `C` implicitly provides the following predefined reference type equality operators: @@ -4522,7 +4522,7 @@ In addition to normal applicability rules ([§12.6.4.2](expressions.md#12642-app - Both operands are a value of a type known to be a *reference_type* or the literal `null`. Furthermore, an identity or explicit reference conversion ([§10.3.5](conversions.md#1035-explicit-reference-conversions)) exists from either operand to the type of the other operand. - One operand is the literal `null`, and the other operand is a value of type `T` where `T` is a *type_parameter* that is not known to be a value type, and does not have the value type constraint. - If at runtime `T` is a non-nullable value type, the result of `==` is `false` and the result of `!=` is `true`. - - If at runtime `T` is a nullable value type, the result is computed from the `HasValue` property of the operand, as described in ([§12.12.10](expressions.md#121210-equality-operators-between-nullable-value-types-and-the-null-literal)). + - If at runtime `T` is a nullable value type, the result is computed from the `HasValue` property of the operand, as described in ([§12.13.10](expressions.md#121310-equality-operators-between-nullable-value-types-and-the-null-literal)). - If at runtime `T` is a reference type, the result is `true` if the operand is `null`, and `false` otherwise. Unless one of these conditions is true, a binding-time error occurs. @@ -4593,7 +4593,7 @@ For an operation of the form `x == y` or `x != y`, if any applicable `operat > False > ``` > -> The `s` and `t` variables refer to two distinct string instances containing the same characters. The first comparison outputs `True` because the predefined string equality operator ([§12.12.8](expressions.md#12128-string-equality-operators)) is selected when both operands are of type `string`. The remaining comparisons all output `False` because the overload of `operator ==` in the `string` type is not applicable when either operand has a binding-time type of `object`. +> The `s` and `t` variables refer to two distinct string instances containing the same characters. The first comparison outputs `True` because the predefined string equality operator ([§12.13.8](expressions.md#12138-string-equality-operators)) is selected when both operands are of type `string`. The remaining comparisons all output `False` because the overload of `operator ==` in the `string` type is not applicable when either operand has a binding-time type of `object`. > > Note that the above technique is not meaningful for value types. The example > @@ -4614,7 +4614,7 @@ For an operation of the form `x == y` or `x != y`, if any applicable `operat > > *end example* -### 12.12.8 String equality operators +### 12.13.8 String equality operators The predefined string equality operators are: @@ -4630,9 +4630,9 @@ Two `string` values are considered equal when one of the following is true: The string equality operators compare string values rather than string references. When two separate string instances contain the exact same sequence of characters, the values of the strings are equal, but the references are different. -> *Note*: As described in [§12.12.7](expressions.md#12127-reference-type-equality-operators), the reference type equality operators can be used to compare string references instead of string values. *end note* +> *Note*: As described in [§12.13.7](expressions.md#12137-reference-type-equality-operators), the reference type equality operators can be used to compare string references instead of string values. *end note* -### 12.12.9 Delegate equality operators +### 12.13.9 Delegate equality operators The predefined delegate equality operators are: @@ -4645,19 +4645,19 @@ Two delegate instances are considered equal as follows: - If either of the delegate instances is `null`, they are equal if and only if both are `null`. - If the delegates have different run-time types, they are never equal. -- If both of the delegate instances have an invocation list ([§20.2](delegates.md#202-delegate-declarations)), those instances are equal if and only if their invocation lists are the same length, and each entry in one’s invocation list is equal (as defined below) to the corresponding entry, in order, in the other’s invocation list. +- If both of the delegate instances have an invocation list ([§21.2](delegates.md#212-delegate-declarations)), those instances are equal if and only if their invocation lists are the same length, and each entry in one’s invocation list is equal (as defined below) to the corresponding entry, in order, in the other’s invocation list. The following rules govern the equality of invocation list entries: - If two invocation list entries both refer to the same static method then the entries are equal. - If two invocation list entries both refer to the same non-static method on the same target object (as defined by the reference equality operators) then the entries are equal. -- Invocation list entries produced from evaluation of semantically identical anonymous functions ([§12.19](expressions.md#1219-anonymous-function-expressions)) with the same (possibly empty) set of captured outer variable instances are permitted (but not required) to be equal. +- Invocation list entries produced from evaluation of semantically identical anonymous functions ([§12.20](expressions.md#1220-anonymous-function-expressions)) with the same (possibly empty) set of captured outer variable instances are permitted (but not required) to be equal. -If operator overload resolution resolves to either delegate equality operator, and the binding-time types of both operands are delegate types as described in [§20](delegates.md#20-delegates) rather than `System.Delegate`, and there is no identity conversion between the binding-type operand types, a binding-time error occurs. +If operator overload resolution resolves to either delegate equality operator, and the binding-time types of both operands are delegate types as described in [§21](delegates.md#21-delegates) rather than `System.Delegate`, and there is no identity conversion between the binding-type operand types, a binding-time error occurs. > *Note*: This rule prevents comparisons which can never consider non-`null` values as equal due to being references to instances of different types of delegates. *end note* -### 12.12.10 Equality operators between nullable value types and the null literal +### 12.13.10 Equality operators between nullable value types and the null literal The `==` and `!=` operators permit one operand to be a value of a nullable value type and the other to be the `null` literal, even if no predefined or user-defined operator (in unlifted or lifted form) exists for the operation. @@ -4669,7 +4669,7 @@ x == null null == x x != null null != x where `x` is an expression of a nullable value type, if operator overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) fails to find an applicable operator, the result is instead computed from the `HasValue` property of `x`. Specifically, the first two forms are translated into `!x.HasValue`, and the last two forms are translated into `x.HasValue`. -### 12.12.11 Tuple equality operators +### 12.13.11 Tuple equality operators The tuple equality operators are applied pairwise to the elements of the tuple operands in lexical order. @@ -4705,11 +4705,11 @@ The tuple equality operator `x != y` is evaluated as follows: - If the resulting `bool` is `true`, then no further evaluation occurs, and the result of the tuple equality operator is `true`. - If all element comparisons yielded `false`, the result of the tuple equality operator is `false`. -### 12.12.12 The is operator +### 12.13.12 The is operator There are two forms of the `is` operator. One is the *is-type operator*, which has a type on the right-hand-side. The other is the *is-pattern operator*, which has a pattern on the right-hand-side. -#### 12.12.12.1 The is-type operator +#### 12.13.12.1 The is-type operator The *is-type operator* is used to check if the run-time type of an object is compatible with a given type. The check is performed at runtime. The result of the operation `E is T`, where `E` is an expression and `T` is a type other than `dynamic`, is a Boolean value indicating whether `E` is non-null and can successfully be converted to type `T` by a reference conversion, a boxing conversion, an unboxing conversion, a wrapping conversion, or an unwrapping conversion. @@ -4749,7 +4749,7 @@ User defined conversions are not considered by the `is` operator. > > *end note* -#### 12.12.12.2 The is-pattern operator +#### 12.13.12.2 The is-pattern operator The *is-pattern operator* is used to check if the value computed by an expression *matches* a given pattern ([§11](patterns.md#11-patterns-and-pattern-matching)). The check is performed at runtime. The result of the is-pattern operator is true if the value matches the pattern; otherwise it is false. @@ -4758,9 +4758,9 @@ For an expression of the form `E is P`, where `E` is a relational expression of - `E` does not designate a value or does not have a type. - The pattern `P` is not applicable ([§11.2](patterns.md#112-pattern-forms)) to the type `T`. -### 12.12.13 The as operator +### 12.13.13 The as operator -The `as` operator is used to explicitly convert a value to a given reference type or nullable value type. Unlike a cast expression ([§12.9.7](expressions.md#1297-cast-expressions)), the `as` operator never throws an exception. Instead, if the indicated conversion is not possible, the resulting value is `null`. +The `as` operator is used to explicitly convert a value to a given reference type or nullable value type. Unlike a cast expression ([§12.9.8](expressions.md#1298-cast-expressions)), the `as` operator never throws an exception. Instead, if the indicated conversion is not possible, the resulting value is `null`. In an operation of the form `E as T`, `E` shall be an expression and `T` shall be a reference type, a type parameter known to be a reference type, or a nullable value type. Furthermore, at least one of the following shall be true, or otherwise a compile-time error occurs: @@ -4812,9 +4812,9 @@ Note that some conversions, such as user defined conversions, are not possible w > > *end example* -## 12.13 Logical operators +## 12.14 Logical operators -### 12.13.1 General +### 12.14.1 General The `&`, `^`, and `|` operators are called the logical operators. @@ -4841,7 +4841,7 @@ For an operation of the form `x «op» y`, where «op» is one of the logical o The predefined logical operators are described in the following subclauses. -### 12.13.2 Integer logical operators +### 12.14.2 Integer logical operators The predefined integer logical operators are: @@ -4866,7 +4866,7 @@ The `&` operator computes the bitwise logical AND of the two operands, the `|` Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined integer logical operators defined above are also predefined. -### 12.13.3 Enumeration logical operators +### 12.14.3 Enumeration logical operators Every enumeration type `E` implicitly provides the following predefined logical operators: @@ -4880,7 +4880,7 @@ The result of evaluating `x «op» y`, where `x` and `y` are expressions of an Lifted ([§12.4.8](expressions.md#1248-lifted-operators)) forms of the unlifted predefined enumeration logical operators defined above are also predefined. -### 12.13.4 Boolean logical operators +### 12.14.4 Boolean logical operators The predefined Boolean logical operators are: @@ -4896,11 +4896,11 @@ The result of `x | y` is `true` if either `x` or `y` is `true`. Otherwise, the The result of `x ^ y` is `true` if `x` is `true` and `y` is `false`, or `x` is `false` and `y` is `true`. Otherwise, the result is `false`. When the operands are of type `bool`, the `^` operator computes the same result as the `!=` operator. -### 12.13.5 Nullable Boolean & and | operators +### 12.14.5 Nullable Boolean & and | operators The nullable Boolean type `bool?` can represent three values, `true`, `false`, and `null`. -As with the other binary operators, lifted forms of the logical operators `&` and `|` ([§12.13.4](expressions.md#12134-boolean-logical-operators)) are also pre-defined: +As with the other binary operators, lifted forms of the logical operators `&` and `|` ([§12.14.4](expressions.md#12144-boolean-logical-operators)) are also pre-defined: ```csharp bool? operator &(bool? x, bool? y); @@ -4923,9 +4923,9 @@ The semantics of the lifted `&` and `|` operators are defined by the following > *Note*: The `bool?` type is conceptually similar to the three-valued type used for Boolean expressions in SQL. The table above follows the same semantics as SQL, whereas applying the rules of [§12.4.8](expressions.md#1248-lifted-operators) to the `&` and `|` operators would not. The rules of [§12.4.8](expressions.md#1248-lifted-operators) already provide SQL-like semantics for the lifted `^` operator. *end note* -## 12.14 Conditional logical operators +## 12.15 Conditional logical operators -### 12.14.1 General +### 12.15.1 General The `&&` and `||` operators are called the conditional logical operators. They are also called the “short-circuiting” logical operators. @@ -4952,20 +4952,20 @@ If an operand of a conditional logical operator has the compile-time type `dynam An operation of the form `x && y` or `x || y` is processed by applying overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) as if the operation was written `x & y` or `x | y`. Then, -- If overload resolution fails to find a single best operator, or if overload resolution selects one of the predefined integer logical operators or nullable Boolean logical operators ([§12.13.5](expressions.md#12135-nullable-boolean--and--operators)), a binding-time error occurs. -- Otherwise, if the selected operator is one of the predefined Boolean logical operators ([§12.13.4](expressions.md#12134-boolean-logical-operators)), the operation is processed as described in [§12.14.2](expressions.md#12142-boolean-conditional-logical-operators). -- Otherwise, the selected operator is a user-defined operator, and the operation is processed as described in [§12.14.3](expressions.md#12143-user-defined-conditional-logical-operators). +- If overload resolution fails to find a single best operator, or if overload resolution selects one of the predefined integer logical operators or nullable Boolean logical operators ([§12.14.5](expressions.md#12145-nullable-boolean--and--operators)), a binding-time error occurs. +- Otherwise, if the selected operator is one of the predefined Boolean logical operators ([§12.14.4](expressions.md#12144-boolean-logical-operators)), the operation is processed as described in [§12.15.2](expressions.md#12152-boolean-conditional-logical-operators). +- Otherwise, the selected operator is a user-defined operator, and the operation is processed as described in [§12.15.3](expressions.md#12153-user-defined-conditional-logical-operators). -It is not possible to directly overload the conditional logical operators. However, because the conditional logical operators are evaluated in terms of the regular logical operators, overloads of the regular logical operators are, with certain restrictions, also considered overloads of the conditional logical operators. This is described further in [§12.14.3](expressions.md#12143-user-defined-conditional-logical-operators). +It is not possible to directly overload the conditional logical operators. However, because the conditional logical operators are evaluated in terms of the regular logical operators, overloads of the regular logical operators are, with certain restrictions, also considered overloads of the conditional logical operators. This is described further in [§12.15.3](expressions.md#12153-user-defined-conditional-logical-operators). -### 12.14.2 Boolean conditional logical operators +### 12.15.2 Boolean conditional logical operators When the operands of `&&` or `||` are of type `bool`, or when the operands are of types that do not define an applicable `operator &` or `operator |`, but do define implicit conversions to `bool`, the operation is processed as follows: - The operation `x && y` is evaluated as `x ? y : false`. In other words, `x` is first evaluated and converted to type `bool`. Then, if `x` is `true`, `y` is evaluated and converted to type `bool`, and this becomes the result of the operation. Otherwise, the result of the operation is `false`. - The operation `x || y` is evaluated as `x ? true : y`. In other words, `x` is first evaluated and converted to type `bool`. Then, if `x` is `true`, the result of the operation is `true`. Otherwise, `y` is evaluated and converted to type `bool`, and this becomes the result of the operation. -### 12.14.3 User-defined conditional logical operators +### 12.15.3 User-defined conditional logical operators When the operands of `&&` or `||` are of types that declare an applicable user-defined `operator &` or `operator |`, both of the following shall be true, where `T` is the type in which the selected operator is declared: @@ -4979,7 +4979,7 @@ A binding-time error occurs if either of these requirements is not satisfied. Ot In either of these operations, the expression given by `x` is only evaluated once, and the expression given by `y` is either not evaluated or evaluated exactly once. -## 12.15 The null coalescing operator +## 12.16 The null coalescing operator The `??` operator is called the null coalescing operator. @@ -5021,7 +5021,7 @@ The type of the expression `a ?? b` depends on which implicit conversions are > > *end example* -## 12.16 The throw expression operator +## 12.17 The throw expression operator ```ANTLR throw_expression @@ -5039,7 +5039,7 @@ A *throw expression* shall only occur in the following syntactic contexts: - As the second operand of a null coalescing operator (`??`). - As the body of an expression-bodied lambda or member. -## 12.17 Declaration expressions +## 12.18 Declaration expressions A declaration expression declares a local variable. @@ -5059,7 +5059,7 @@ The *simple_name* `_` is also considered a declaration expression if simple name A declaration expression shall only occur in the following syntactic contexts: - As an `out` *argument_value* in an *argument_list*. -- As a simple discard `_` comprising the left side of a simple assignment ([§12.21.2](expressions.md#12212-simple-assignment)). +- As a simple discard `_` comprising the left side of a simple assignment ([§12.22.2](expressions.md#12222-simple-assignment)). - As a *tuple_element* in one or more recursively nested *tuple_expression*s, the outermost of which comprises the left side of a deconstructing assignment. A *deconstruction_expression* gives rise to declaration expressions in this position, even though the declaration expressions are not syntactically present. > *Note*: This means that a declaration expression cannot be parenthesized. *end note* @@ -5119,7 +5119,7 @@ A declaration expression with the identifier `_` is a discard ([§9.2.9.2](varia > > *end example* -## 12.18 Conditional operator +## 12.19 Conditional operator The `?:` operator is called the conditional operator. It is at times also called the ternary operator. @@ -5132,7 +5132,7 @@ conditional_expression ; ``` -A throw expression ([§12.16](expressions.md#1216-the-throw-expression-operator)) is not allowed in a conditional operator if `ref` is present. +A throw expression ([§12.17](expressions.md#1217-the-throw-expression-operator)) is not allowed in a conditional operator if `ref` is present. A conditional expression of the form `b ? x : y` first evaluates the condition `b`. Then, if `b` is `true`, `x` is evaluated and becomes the result of the operation. Otherwise, `y` is evaluated and becomes the result of the operation. A conditional expression never evaluates both `x` and `y`. @@ -5177,9 +5177,9 @@ The run-time processing of a conditional expression of the form `b ? x : y` - If the `bool` value produced by the step above is `true`, then `x` is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression. - Otherwise, `y` is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression. -## 12.19 Anonymous function expressions +## 12.20 Anonymous function expressions -### 12.19.1 General +### 12.20.1 General An ***anonymous function*** is an expression that represents an “in-line” method definition. An anonymous function does not have a value or type in and of itself, but is convertible to a compatible delegate or expression-tree type. The evaluation of an anonymous-function conversion depends on the target type of the conversion: If it is a delegate type, the conversion evaluates to a delegate value referencing the method that the anonymous function defines. If it is an expression-tree type, the conversion evaluates to an expression tree that represents the structure of the method as an object structure. @@ -5306,7 +5306,7 @@ The behavior of *lambda_expression*s and *anonymous_method_expression*s is the s - The body of a *lambda_expression* can be an expression or a block whereas the body of an *anonymous_method_expression* shall be a block. - Only *lambda_expression*s have conversions to compatible expression tree types ([§8.6](types.md#86-expression-tree-types)). -### 12.19.2 Anonymous function signatures +### 12.20.2 Anonymous function signatures The *anonymous_function_signature* of an anonymous function defines the names and optionally the types of the parameters for the anonymous function. The scope of the parameters of the anonymous function is the *anonymous_function_body* ([§7.7](basic-concepts.md#77-scopes)). Together with the parameter list (if given) the anonymous-method-body constitutes a declaration space ([§7.3](basic-concepts.md#73-declarations)). It is thus a compile-time error for the name of a parameter of the anonymous function to match the name of a local variable, local constant or parameter whose scope includes the *anonymous_method_expression* or *lambda_expression*. @@ -5316,7 +5316,7 @@ Note that an *anonymous_function_signature* cannot include attributes or a param Note also that conversion to an expression tree type, even if compatible, may still fail at compile-time ([§8.6](types.md#86-expression-tree-types)). -### 12.19.3 Anonymous function bodies +### 12.20.3 Anonymous function bodies The body (*expression* or *block*) of an anonymous function is subject to the following rules: @@ -5324,13 +5324,13 @@ The body (*expression* or *block*) of an anonymous function is subject to the fo - Except for by-reference parameters specified in the signature (if any) of the nearest enclosing anonymous function, it is a compile-time error for the body to access a by-reference parameter. - Except for parameters specified in the signature (if any) of the nearest enclosing anonymous function, it is a compile-time error for the body to access a parameter of a `ref struct` type. - When the type of `this` is a struct type, it is a compile-time error for the body to access `this`. This is true whether the access is explicit (as in `this.x`) or implicit (as in `x` where `x` is an instance member of the struct). This rule simply prohibits such access and does not affect whether member lookup results in a member of the struct. -- The body has access to the outer variables ([§12.19.6](expressions.md#12196-outer-variables)) of the anonymous function. Access of an outer variable will reference the instance of the variable that is active at the time the *lambda_expression* or *anonymous_method_expression* is evaluated ([§12.19.7](expressions.md#12197-evaluation-of-anonymous-function-expressions)). +- The body has access to the outer variables ([§12.20.6](expressions.md#12206-outer-variables)) of the anonymous function. Access of an outer variable will reference the instance of the variable that is active at the time the *lambda_expression* or *anonymous_method_expression* is evaluated ([§12.20.7](expressions.md#12207-evaluation-of-anonymous-function-expressions)). - It is a compile-time error for the body to contain a `goto` statement, a `break` statement, or a `continue` statement whose target is outside the body or within the body of a contained anonymous function. - A `return` statement in the body returns control from an invocation of the nearest enclosing anonymous function, not from the enclosing function member. It is explicitly unspecified whether there is any way to execute the block of an anonymous function other than through evaluation and invocation of the *lambda_expression* or *anonymous_method_expression*. In particular, a compiler may choose to implement an anonymous function by synthesizing one or more named methods or types. The names of any such synthesized elements shall be of a form reserved for compiler use ([§6.4.3](lexical-structure.md#643-identifiers)). -### 12.19.4 Overload resolution +### 12.20.4 Overload resolution Anonymous functions in an argument list participate in type inference and overload resolution. Refer to [§12.6.3](expressions.md#1263-type-inference) and [§12.6.4](expressions.md#1264-overload-resolution) for the exact rules. @@ -5399,17 +5399,17 @@ Anonymous functions in an argument list participate in type inference and overlo > > *end example* -### 12.19.5 Anonymous functions and dynamic binding +### 12.20.5 Anonymous functions and dynamic binding An anonymous function cannot be a receiver, argument, or operand of a dynamically bound operation. -### 12.19.6 Outer variables +### 12.20.6 Outer variables -#### 12.19.6.1 General +#### 12.20.6.1 General Any local variable, value parameter, or parameter array whose scope includes the *lambda_expression* or *anonymous_method_expression* is called an ***outer variable*** of the anonymous function. In an instance function member of a class, the this value is considered a value parameter and is an outer variable of any anonymous function contained within the function member. -#### 12.19.6.2 Captured outer variables +#### 12.20.6.2 Captured outer variables When an outer variable is referenced by an anonymous function, the outer variable is said to have been ***captured*** by the anonymous function. Ordinarily, the lifetime of a local variable is limited to execution of the block or statement with which it is associated ([§9.2.9.1](variables.md#9291-general)). However, the lifetime of a captured outer variable is extended at least until the delegate or expression tree created from the anonymous function becomes eligible for garbage collection. @@ -5448,11 +5448,11 @@ When an outer variable is referenced by an anonymous function, the outer variabl > > *end example* -When a local variable or a value parameter is captured by an anonymous function, the local variable or parameter is no longer considered to be a fixed variable ([§23.4](unsafe-code.md#234-fixed-and-moveable-variables)), but is instead considered to be a moveable variable. However, captured outer variables cannot be used in a `fixed` statement ([§23.7](unsafe-code.md#237-the-fixed-statement)), so the address of a captured outer variable cannot be taken. +When a local variable or a value parameter is captured by an anonymous function, the local variable or parameter is no longer considered to be a fixed variable ([§24.4](unsafe-code.md#244-fixed-and-moveable-variables)), but is instead considered to be a moveable variable. However, captured outer variables cannot be used in a `fixed` statement ([§24.7](unsafe-code.md#247-the-fixed-statement)), so the address of a captured outer variable cannot be taken. > *Note*: Unlike an uncaptured variable, a captured local variable can be simultaneously exposed to multiple threads of execution. *end note* -#### 12.19.6.3 Instantiation of local variables +#### 12.20.6.3 Instantiation of local variables A local variable is considered to be ***instantiated*** when execution enters the scope of the variable. @@ -5669,11 +5669,11 @@ Separate anonymous functions can capture the same instance of an outer variable. > > *end example* -### 12.19.7 Evaluation of anonymous function expressions +### 12.20.7 Evaluation of anonymous function expressions An anonymous function `F` shall always be converted to a delegate type `D` or an expression-tree type `E`, either directly or through the execution of a delegate creation expression `new D(F)`. This conversion determines the result of the anonymous function, as described in [§10.7](conversions.md#107-anonymous-function-conversions). -### 12.19.8 Implementation Example +### 12.20.8 Implementation Example **This subclause is informative.** @@ -5775,7 +5775,7 @@ class Test } ``` -The lifetime of the local variable must now be extended to at least the lifetime of the anonymous function delegate. This can be achieved by “hoisting” the local variable into a field of a compiler-generated class. Instantiation of the local variable ([§12.19.6.3](expressions.md#121963-instantiation-of-local-variables)) then corresponds to creating an instance of the compiler-generated class, and accessing the local variable corresponds to accessing a field in the instance of the compiler-generated class. Furthermore, the anonymous function becomes an instance method of the compiler-generated class: +The lifetime of the local variable must now be extended to at least the lifetime of the anonymous function delegate. This can be achieved by “hoisting” the local variable into a field of a compiler-generated class. Instantiation of the local variable ([§12.20.6.3](expressions.md#122063-instantiation-of-local-variables)) then corresponds to creating an instance of the compiler-generated class, and accessing the local variable corresponds to accessing a field in the instance of the compiler-generated class. Furthermore, the anonymous function becomes an instance method of the compiler-generated class: ```csharp @@ -5871,9 +5871,9 @@ The same technique applied here to capture local variables can also be used when **End of informative text.** -## 12.20 Query expressions +## 12.21 Query expressions -### 12.20.1 General +### 12.21.1 General ***Query expressions*** provide a language-integrated syntax for queries that is similar to relational and hierarchical query languages such as SQL and XQuery. @@ -5954,17 +5954,17 @@ query_continuation A query expression begins with a `from` clause and ends with either a `select` or `group` clause. The initial `from` clause may be followed by zero or more `from`, `let`, `where`, `join` or `orderby` clauses. Each `from` clause is a generator introducing a ***range variable*** that ranges over the elements of a ***sequence***. Each `let` clause introduces a range variable representing a value computed by means of previous range variables. Each `where` clause is a filter that excludes items from the result. Each `join` clause compares specified keys of the source sequence with keys of another sequence, yielding matching pairs. Each `orderby` clause reorders items according to specified criteria.The final `select` or `group` clause specifies the shape of the result in terms of the range variables. Finally, an `into` clause can be used to “splice” queries by treating the results of one query as a generator in a subsequent query. -### 12.20.2 Ambiguities in query expressions +### 12.21.2 Ambiguities in query expressions Query expressions use a number of contextual keywords ([§6.4.4](lexical-structure.md#644-keywords)): `ascending`, `by`, `descending`, `equals`, `from`, `group`, `into`, `join`, `let`, `on`, `orderby`, `select` and `where`. To avoid ambiguities that could arise from the use of these identifiers both as keywords and simple names these identifiers are considered keywords anywhere within a query expression, unless they are prefixed with “`@`” ([§6.4.4](lexical-structure.md#644-keywords)) in which case they are considered identifiers. For this purpose, a query expression is any expression that starts with “`from` *identifier*” followed by any token except “`;`”, “`=`” or “`,`”. -### 12.20.3 Query expression translation +### 12.21.3 Query expression translation -#### 12.20.3.1 General +#### 12.21.3.1 General -The C# language does not specify the execution semantics of query expressions. Rather, query expressions are translated into invocations of methods that adhere to the query-expression pattern ([§12.20.4](expressions.md#12204-the-query-expression-pattern)). Specifically, query expressions are translated into invocations of methods named `Where`, `Select`, `SelectMany`, `Join`, `GroupJoin`, `OrderBy`, `OrderByDescending`, `ThenBy`, `ThenByDescending`, `GroupBy`, and `Cast`. These methods are expected to have particular signatures and return types, as described in [§12.20.4](expressions.md#12204-the-query-expression-pattern). These methods may be instance methods of the object being queried or extension methods that are external to the object. These methods implement the actual execution of the query. +The C# language does not specify the execution semantics of query expressions. Rather, query expressions are translated into invocations of methods that adhere to the query-expression pattern ([§12.21.4](expressions.md#12214-the-query-expression-pattern)). Specifically, query expressions are translated into invocations of methods named `Where`, `Select`, `SelectMany`, `Join`, `GroupJoin`, `OrderBy`, `OrderByDescending`, `ThenBy`, `ThenByDescending`, `GroupBy`, and `Cast`. These methods are expected to have particular signatures and return types, as described in [§12.21.4](expressions.md#12214-the-query-expression-pattern). These methods may be instance methods of the object being queried or extension methods that are external to the object. These methods implement the actual execution of the query. The translation from query expressions to method invocations is a syntactic mapping that occurs before any type binding or overload resolution has been performed. Following translation of query expressions, the resulting method invocations are processed as regular method invocations, and this may in turn uncover compile time errors. These error conditions include, but are not limited to, methods that do not exist, arguments of the wrong types, and generic methods where type inference fails. @@ -5972,9 +5972,9 @@ A query expression is processed by repeatedly applying the following translation It is a compile time error for a query expression to include an assignment to a range variable, or the use of a range variable as an argument for a reference or output parameter. -Certain translations inject range variables with *transparent identifiers* denoted by \*. These are described further in [§12.20.3.8](expressions.md#122038-transparent-identifiers). +Certain translations inject range variables with *transparent identifiers* denoted by \*. These are described further in [§12.21.3.8](expressions.md#122138-transparent-identifiers). -#### 12.20.3.2 Query expressions with continuations +#### 12.21.3.2 Query expressions with continuations A query expression with a continuation following its query body @@ -6017,7 +6017,7 @@ The translations in the following sections assume that queries have no continuat > > *end example* -#### 12.20.3.3 Explicit range variable types +#### 12.21.3.3 Explicit range variable types A `from` clause that explicitly specifies a range variable type @@ -6075,7 +6075,7 @@ The translations in the following sections assume that queries have no explicit > *Note*: Explicit range variable types are useful for querying collections that implement the non-generic `IEnumerable` interface, but not the generic `IEnumerable` interface. In the example above, this would be the case if customers were of type `ArrayList`. *end note* -#### 12.20.3.4 Degenerate query expressions +#### 12.21.3.4 Degenerate query expressions A query expression of the form @@ -6106,9 +6106,9 @@ is translated into A degenerate query expression is one that trivially selects the elements of the source. -> *Note*: Later phases of the translation ([§12.20.3.6](expressions.md#122036-select-clauses) and [§12.20.3.7](expressions.md#122037-group-clauses)) remove degenerate queries introduced by other translation steps by replacing them with their source. It is important, however, to ensure that the result of a query expression is never the source object itself. Otherwise, returning the result of such a query might inadvertently expose private data (e.g., an element array) to a caller. Therefore this step protects degenerate queries written directly in source code by explicitly calling `Select` on the source. It is then up to the implementers of `Select` and other query operators to ensure that these methods never return the source object itself. *end note* +> *Note*: Later phases of the translation ([§12.21.3.6](expressions.md#122136-select-clauses) and [§12.21.3.7](expressions.md#122137-group-clauses)) remove degenerate queries introduced by other translation steps by replacing them with their source. It is important, however, to ensure that the result of a query expression is never the source object itself. Otherwise, returning the result of such a query might inadvertently expose private data (e.g., an element array) to a caller. Therefore this step protects degenerate queries written directly in source code by explicitly calling `Select` on the source. It is then up to the implementers of `Select` and other query operators to ensure that these methods never return the source object itself. *end note* -#### 12.20.3.5 From, let, where, join and orderby clauses +#### 12.21.3.5 From, let, where, join and orderby clauses A query expression with a second `from` clause followed by a `select` clause @@ -6414,7 +6414,7 @@ If an `ordering` clause specifies a descending direction indicator, an invocatio The following translations assume that there are no `let`, `where`, `join` or `orderby` clauses, and no more than the one initial `from` clause in each query expression. -#### 12.20.3.6 Select clauses +#### 12.21.3.6 Select clauses A query expression of the form @@ -6449,7 +6449,7 @@ except when `«v»` is the identifier `«x»`, the translation is simply > > *end example* -#### 12.20.3.7 Group clauses +#### 12.21.3.7 Group clauses A `group` clause @@ -6484,7 +6484,7 @@ except when `«v»` is the identifier `«x»`, the translation is > > *end example* -#### 12.20.3.8 Transparent identifiers +#### 12.21.3.8 Transparent identifiers Certain translations inject range variables with ***transparent identifiers*** denoted by `*`. Transparent identifiers exist only as an intermediate step in the query-expression translation process. @@ -6581,7 +6581,7 @@ In the translation steps described above, transparent identifiers are always int > where `x` and `y` are compiler-generated identifiers that are otherwise invisible and inaccessible. > *end example* -### 12.20.4 The query-expression pattern +### 12.21.4 The query-expression pattern The ***Query-expression pattern*** establishes a pattern of methods that types can implement to support query expressions. @@ -6642,9 +6642,9 @@ The methods above use the generic delegate types `Func` and `Func > *Note*: The `System.Linq` namespace provides an implementation of the query-expression pattern for any type that implements the `System.Collections.Generic.IEnumerable` interface. *end note* -## 12.21 Assignment operators +## 12.22 Assignment operators -### 12.21.1 General +### 12.22.1 General All but one of the assignment operators assigns a new value to a variable, a property, an event, or an indexer element. The exception, `= ref`, assigns a variable reference ([§9.5](variables.md#95-variable-references)) to a reference variable ([§9.7](variables.md#97-reference-variables-and-returns)). @@ -6661,22 +6661,22 @@ assignment_operator The left operand of an assignment shall be an expression classified as a variable, or, except for `= ref`, a property access, an indexer access, an event access or a tuple. A declaration expression is not directly permitted as a left operand, but may occur as a step in the evaluation of a deconstructing assignment. -The `=` operator is called the ***simple assignment operator***. It assigns the value or values of the right operand to the variable, property, indexer element or tuple elements given by the left operand. The left operand of the simple assignment operator shall not be an event access (except as described in [§15.8.2](classes.md#1582-field-like-events)). The simple assignment operator is described in [§12.21.2](expressions.md#12212-simple-assignment). +The `=` operator is called the ***simple assignment operator***. It assigns the value or values of the right operand to the variable, property, indexer element or tuple elements given by the left operand. The left operand of the simple assignment operator shall not be an event access (except as described in [§15.8.2](classes.md#1582-field-like-events)). The simple assignment operator is described in [§12.22.2](expressions.md#12222-simple-assignment). -The operator `= ref` is called the ***ref assignment operator***. It makes the right operand, which shall be a *variable_reference* ([§9.5](variables.md#95-variable-references)), the referent of the reference variable designated by the left operand. The ref assignment operator is described in [§12.21.3](expressions.md#12213-ref-assignment). +The operator `= ref` is called the ***ref assignment operator***. It makes the right operand, which shall be a *variable_reference* ([§9.5](variables.md#95-variable-references)), the referent of the reference variable designated by the left operand. The ref assignment operator is described in [§12.22.3](expressions.md#12223-ref-assignment). The assignment operators other than the `=` and `= ref` operator are called the ***compound assignment operators***. These operators are processed as follows: - For the `??=` operator, only if the value of the left-operand is `null`, is the right-operand evaluated and the result assigned to the variable, property, or indexer element given by the left operand. -- Otherwise, the indicated operation is performed on the two operands, and then the resulting value is assigned to the variable, property, or indexer element given by the left operand. The compound assignment operators are described in [§12.21.4](expressions.md#12214-compound-assignment). +- Otherwise, the indicated operation is performed on the two operands, and then the resulting value is assigned to the variable, property, or indexer element given by the left operand. The compound assignment operators are described in [§12.22.4](expressions.md#12224-compound-assignment). -The `+=` and `-=` operators with an event access expression as the left operand are called the ***event assignment operators***. No other assignment operator is valid with an event access as the left operand. The event assignment operators are described in [§12.21.5](expressions.md#12215-event-assignment). +The `+=` and `-=` operators with an event access expression as the left operand are called the ***event assignment operators***. No other assignment operator is valid with an event access as the left operand. The event assignment operators are described in [§12.22.5](expressions.md#12225-event-assignment). The assignment operators are right-associative, meaning that operations are grouped from right to left. > *Example*: An expression of the form `a = b = c` is evaluated as `a = (b = c)`. *end example* -### 12.21.2 Simple assignment +### 12.22.2 Simple assignment The `=` operator is called the simple assignment operator. @@ -6811,7 +6811,7 @@ When a property or indexer declared in a *struct_type* is the target of an assig > > *end example* -### 12.21.3 Ref assignment +### 12.22.3 Ref assignment The `= ref` operator is known as the *ref assignment* operator. @@ -6861,7 +6861,7 @@ The ref assignment operator shall not read the storage location referenced by th > *Note*: When reading code using an `= ref` operator, it can be tempting to read the `ref` part as being part of the operand. This is particularly confusing when the operand is a conditional `?:` expression. For example, when reading `ref int a = ref b ? ref x : ref y;` it’s important to read this as `= ref` being the operator, and `b ? ref x : ref y` being the right operand: `ref int a = ref (b ? ref x : ref y);`. Importantly, the expression `ref b` is *not* part of that statement, even though it might appear so at first glance. *end note* -### 12.21.4 Compound assignment +### 12.22.4 Compound assignment If the left operand of a compound assignment is of the form `E.P` or `E[Ei]` where `E` has the compile-time type `dynamic`, then the assignment is dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). In this case, the compile-time type of the assignment expression is `dynamic`, and the resolution described below will take place at run-time based on the run-time type of `E`. If the left operand is of the form `E[Ei]` where at least one element of `Ei` has the compile-time type `dynamic`, and the compile-time type of `E` is not an array, the resulting indexer access is dynamically bound, but with limited compile-time checking ([§12.6.5](expressions.md#1265-compile-time-checking-of-dynamic-member-invocation)). @@ -6906,7 +6906,7 @@ The intuitive effect of the rule for predefined operators is simply that `x «op > *Note*: This also means that compound assignment operations support lifted operators. Since a compound assignment `x «op»= y` is evaluated as either `x = x «op» y` or `x = (T)(x «op» y)`, the rules of evaluation implicitly cover lifted operators. *end note* -### 12.21.5 Event assignment +### 12.22.5 Event assignment If the left operand of `a += or -=` operator is classified as an event access, then the expression is evaluated as follows: @@ -6916,7 +6916,7 @@ If the left operand of `a += or -=` operator is classified as an event access, An event assignment expression does not yield a value. Thus, an event assignment expression is valid only in the context of a *statement_expression* ([§13.7](statements.md#137-expression-statements)). -## 12.22 Expression +## 12.23 Expression An *expression* is either a *non_assignment_expression* or an *assignment*. @@ -6934,7 +6934,7 @@ non_assignment_expression ; ``` -## 12.23 Constant expressions +## 12.24 Constant expressions A constant expression is an expression that shall be fully evaluated at compile-time. @@ -6964,7 +6964,7 @@ Only the following constructs are permitted in constant expressions: - The predefined `+`, `-`, `*`, `/`, `%`, `<<`, `>>`, `&`, `|`, `^`, `&&`, `||`, `==`, `!=`, `<`, `>`, `<=`, and `>=` binary operators. - The `?:` conditional operator. - The `!` null-forgiving operator ([§12.8.9](expressions.md#1289-null-forgiving-expressions)). -- `sizeof` expressions, provided the unmanaged-type is one of the types specified in [§23.6.9](unsafe-code.md#2369-the-sizeof-operator) for which `sizeof` returns a constant value. +- `sizeof` expressions, provided the unmanaged-type is one of the types specified in [§24.6.9](unsafe-code.md#2469-the-sizeof-operator) for which `sizeof` returns a constant value. - Default value expressions, provided the type is one of the types listed above. The following conversions are permitted in constant expressions: @@ -7003,17 +7003,17 @@ Unless a constant expression is explicitly placed in an `unchecked` context, ove Constant expressions are required in the contexts listed below and this is indicated in the grammar by using *constant_expression*. In these contexts, a compile-time error occurs if an expression cannot be fully evaluated at compile-time. - Constant declarations ([§15.4](classes.md#154-constants)) -- Enumeration member declarations ([§19.4](enums.md#194-enum-members)) +- Enumeration member declarations ([§20.4](enums.md#204-enum-members)) - Default arguments of parameter lists ([§15.6.2](classes.md#1562-method-parameters)) - `case` labels of a `switch` statement ([§13.8.3](statements.md#1383-the-switch-statement)). - `goto case` statements ([§13.10.4](statements.md#13104-the-goto-statement)) - Dimension lengths in an array creation expression ([§12.8.17.4](expressions.md#128174-array-creation-expressions)) that includes an initializer. -- Attributes ([§22](attributes.md#22-attributes)) +- Attributes ([§23](attributes.md#23-attributes)) - In a *constant_pattern* ([§11.2.3](patterns.md#1123-constant-pattern)) An implicit constant expression conversion ([§10.2.11](conversions.md#10211-implicit-constant-expression-conversions)) permits a constant expression of type `int` to be converted to `sbyte`, `byte`, `short`, `ushort`, `uint`, or `ulong`, provided the value of the constant expression is within the range of the destination type. -## 12.24 Boolean expressions +## 12.25 Boolean expressions A *boolean_expression* is an expression that yields a result of type `bool`; either directly or through application of `operator true` in certain contexts as specified in the following: @@ -7023,7 +7023,7 @@ boolean_expression ; ``` -The controlling conditional expression of an *if_statement* ([§13.8.2](statements.md#1382-the-if-statement)), *while_statement* ([§13.9.2](statements.md#1392-the-while-statement)), *do_statement* ([§13.9.3](statements.md#1393-the-do-statement)), or *for_statement* ([§13.9.4](statements.md#1394-the-for-statement)) is a *boolean_expression*. The controlling conditional expression of the `?:` operator ([§12.18](expressions.md#1218-conditional-operator)) follows the same rules as a *boolean_expression*, but for reasons of operator precedence is classified as a *null_coalescing_expression*. +The controlling conditional expression of an *if_statement* ([§13.8.2](statements.md#1382-the-if-statement)), *while_statement* ([§13.9.2](statements.md#1392-the-while-statement)), *do_statement* ([§13.9.3](statements.md#1393-the-do-statement)), or *for_statement* ([§13.9.4](statements.md#1394-the-for-statement)) is a *boolean_expression*. The controlling conditional expression of the `?:` operator ([§12.19](expressions.md#1219-conditional-operator)) follows the same rules as a *boolean_expression*, but for reasons of operator precedence is classified as a *null_coalescing_expression*. A *boolean_expression* `E` is required to be able to produce a value of type `bool`, as follows: diff --git a/standard/grammar.md b/standard/grammar.md index 56eb1109c..cc8de540b 100644 --- a/standard/grammar.md +++ b/standard/grammar.md @@ -373,11 +373,11 @@ null_literal // Source: §6.4.6 Operators and punctuators operator_or_punctuator - : '{' | '}' | '[' | ']' | '(' | ')' | '.' | ',' | ':' | ';' - | '+' | '-' | ASTERISK | SLASH | '%' | '&' | '|' | '^' | '!' | '~' - | '=' | '<' | '>' | '?' | '??' | '::' | '++' | '--' | '&&' | '||' - | '->' | '==' | '!=' | '<=' | '>=' | '+=' | '-=' | '*=' | '/=' | '%=' - | '&=' | '|=' | '^=' | '<<' | '<<=' | '=>' | '??=' + : '{' | '}' | '[' | ']' | '(' | ')' | '.' | ',' | ':' | ';' + | '+' | '-' | '*' | '/' | '%' | '&' | '|' | '^' | '!' | '~' + | '=' | '<' | '>' | '?' | '??' | '::' | '++' | '--' | '&&' | '||' + | '->' | '==' | '!=' | '<=' | '>=' | '+=' | '-=' | '*=' | '/=' | '%=' + | '&=' | '|=' | '^=' | '<<' | '<<=' | '=>' | '??=' | '..' ; right_shift @@ -1216,6 +1216,7 @@ unary_expression | '-' unary_expression | logical_negation_operator unary_expression | '~' unary_expression + | '^' unary_expression | pre_increment_expression | pre_decrement_expression | cast_expression @@ -1224,7 +1225,7 @@ unary_expression | addressof_expression // unsafe code support ; -// Source: §12.9.6 Prefix increment and decrement operators +// Source: §12.9.7 Prefix increment and decrement operators pre_increment_expression : '++' unary_expression ; @@ -1233,22 +1234,28 @@ pre_decrement_expression : '--' unary_expression ; -// Source: §12.9.7 Cast expressions +// Source: §12.9.8 Cast expressions cast_expression : '(' type ')' unary_expression ; -// Source: §12.9.8.1 General +// Source: §12.9.9.1 General await_expression : 'await' unary_expression ; -// Source: §12.10.1 General -multiplicative_expression +// Source: §12.10 Range operator +range_expression : unary_expression - | multiplicative_expression '*' unary_expression - | multiplicative_expression '/' unary_expression - | multiplicative_expression '%' unary_expression + | unary_expression? '..' unary_expression? + ; + +// Source: §12.11.1 General +multiplicative_expression + : range_expression + | multiplicative_expression '*' range_expression + | multiplicative_expression '/' range_expression + | multiplicative_expression '%' range_expression ; additive_expression @@ -1257,14 +1264,14 @@ additive_expression | additive_expression '-' multiplicative_expression ; -// Source: §12.11 Shift operators +// Source: §12.12 Shift operators shift_expression : additive_expression | shift_expression '<<' additive_expression | shift_expression right_shift additive_expression ; -// Source: §12.12.1 General +// Source: §12.13.1 General relational_expression : shift_expression | relational_expression '<' shift_expression @@ -1282,7 +1289,7 @@ equality_expression | equality_expression '!=' relational_expression ; -// Source: §12.13.1 General +// Source: §12.14.1 General and_expression : equality_expression | and_expression '&' equality_expression @@ -1298,7 +1305,7 @@ inclusive_or_expression | inclusive_or_expression '|' exclusive_or_expression ; -// Source: §12.14.1 General +// Source: §12.15.1 General conditional_and_expression : inclusive_or_expression | conditional_and_expression '&&' inclusive_or_expression @@ -1309,19 +1316,19 @@ conditional_or_expression | conditional_or_expression '||' conditional_and_expression ; -// Source: §12.15 The null coalescing operator +// Source: §12.16 The null coalescing operator null_coalescing_expression : conditional_or_expression | conditional_or_expression '??' null_coalescing_expression | throw_expression ; -// Source: §12.16 The throw expression operator +// Source: §12.17 The throw expression operator throw_expression : 'throw' null_coalescing_expression ; -// Source: §12.17 Declaration expressions +// Source: §12.18 Declaration expressions declaration_expression : local_variable_type identifier ; @@ -1331,7 +1338,7 @@ local_variable_type | 'var' ; -// Source: §12.18 Conditional operator +// Source: §12.19 Conditional operator conditional_expression : null_coalescing_expression | null_coalescing_expression '?' expression ':' expression @@ -1339,7 +1346,7 @@ conditional_expression 'ref' variable_reference ; -// Source: §12.19.1 General +// Source: §12.20.1 General lambda_expression : 'async'? anonymous_function_signature '=>' anonymous_function_body ; @@ -1393,7 +1400,7 @@ anonymous_function_body | block ; -// Source: §12.20.1 General +// Source: §12.21.1 General query_expression : from_clause query_body ; @@ -1467,7 +1474,7 @@ query_continuation : 'into' identifier query_body ; -// Source: §12.21.1 General +// Source: §12.22.1 General assignment : unary_expression assignment_operator expression ; @@ -1477,7 +1484,7 @@ assignment_operator | right_shift_assignment ; -// Source: §12.22 Expression +// Source: §12.23 Expression expression : non_assignment_expression | assignment @@ -1490,12 +1497,12 @@ non_assignment_expression | query_expression ; -// Source: §12.23 Constant expressions +// Source: §12.24 Constant expressions constant_expression : expression ; -// Source: §12.24 Boolean expressions +// Source: §12.25 Boolean expressions boolean_expression : expression ; @@ -2477,14 +2484,14 @@ variable_initializer | array_initializer ; -// Source: §18.2.1 General +// Source: §19.2.1 General interface_declaration : attributes? interface_modifier* 'partial'? 'interface' identifier variant_type_parameter_list? interface_base? type_parameter_constraints_clause* interface_body ';'? ; -// Source: §18.2.2 Interface modifiers +// Source: §19.2.2 Interface modifiers interface_modifier : 'new' | 'public' @@ -2494,7 +2501,7 @@ interface_modifier | unsafe_modifier // unsafe code support ; -// Source: §18.2.3.1 General +// Source: §19.2.3.1 General variant_type_parameter_list : '<' variant_type_parameter (',' variant_type_parameter)* '>' ; @@ -2508,17 +2515,17 @@ variance_annotation | 'out' ; -// Source: §18.2.4 Base interfaces +// Source: §19.2.4 Base interfaces interface_base : ':' interface_type_list ; -// Source: §18.3 Interface body +// Source: §19.3 Interface body interface_body : '{' interface_member_declaration* '}' ; -// Source: §18.4.1 General +// Source: §19.4.1 General interface_member_declaration : interface_method_declaration | interface_property_declaration @@ -2526,7 +2533,7 @@ interface_member_declaration | interface_indexer_declaration ; -// Source: §18.4.2 Interface methods +// Source: §19.4.2 Interface methods interface_method_declaration : attributes? 'new'? return_type interface_method_header | attributes? 'new'? ref_kind ref_return_type interface_method_header @@ -2538,7 +2545,7 @@ interface_method_header type_parameter_constraints_clause* ';' ; -// Source: §18.4.3 Interface properties +// Source: §19.4.3 Interface properties interface_property_declaration : attributes? 'new'? type identifier '{' interface_accessors '}' | attributes? 'new'? ref_kind type identifier '{' ref_interface_accessor '}' @@ -2555,12 +2562,12 @@ ref_interface_accessor : attributes? 'get' ';' ; -// Source: §18.4.4 Interface events +// Source: §19.4.4 Interface events interface_event_declaration : attributes? 'new'? 'event' type identifier ';' ; -// Source: §18.4.5 Interface indexers +// Source: §19.4.5 Interface indexers interface_indexer_declaration : attributes? 'new'? type 'this' '[' parameter_list ']' '{' interface_accessors '}' @@ -2568,7 +2575,7 @@ interface_indexer_declaration '{' ref_interface_accessor '}' ; -// Source: §19.2 Enum declarations +// Source: §20.2 Enum declarations enum_declaration : attributes? enum_modifier* 'enum' identifier enum_base? enum_body ';'? ; @@ -2587,7 +2594,7 @@ enum_body | '{' enum_member_declarations ',' '}' ; -// Source: §19.3 Enum modifiers +// Source: §20.3 Enum modifiers enum_modifier : 'new' | 'public' @@ -2596,17 +2603,17 @@ enum_modifier | 'private' ; -// Source: §19.4 Enum members +// Source: §20.4 Enum members enum_member_declarations : enum_member_declaration (',' enum_member_declaration)* ; -// Source: §19.4 Enum members +// Source: §20.4 Enum members enum_member_declaration : attributes? identifier ('=' constant_expression)? ; -// Source: §20.2 Delegate declarations +// Source: §21.2 Delegate declarations delegate_declaration : attributes? delegate_modifier* 'delegate' return_type delegate_header | attributes? delegate_modifier* 'delegate' ref_kind ref_return_type @@ -2628,7 +2635,7 @@ delegate_modifier | unsafe_modifier // unsafe code support ; -// Source: §22.3 Attribute specification +// Source: §23.3 Attribute specification global_attributes : global_attribute_section+ ; @@ -2705,7 +2712,7 @@ attribute_argument_expression ```ANTLR -// Source: §23.2 Unsafe contexts +// Source: §24.2 Unsafe contexts unsafe_modifier : 'unsafe' ; @@ -2714,33 +2721,33 @@ unsafe_statement : 'unsafe' block ; -// Source: §23.3 Pointer types +// Source: §24.3 Pointer types pointer_type : value_type ('*')+ | 'void' ('*')+ ; -// Source: §23.6.2 Pointer indirection +// Source: §24.6.2 Pointer indirection pointer_indirection_expression : '*' unary_expression ; -// Source: §23.6.3 Pointer member access +// Source: §24.6.3 Pointer member access pointer_member_access : primary_expression '->' identifier type_argument_list? ; -// Source: §23.6.4 Pointer element access +// Source: §24.6.4 Pointer element access pointer_element_access : primary_expression '[' expression ']' ; -// Source: §23.6.5 The address-of operator +// Source: §24.6.5 The address-of operator addressof_expression : '&' unary_expression ; -// Source: §23.7 The fixed statement +// Source: §24.7 The fixed statement fixed_statement : 'fixed' '(' pointer_type fixed_pointer_declarators ')' embedded_statement ; @@ -2758,7 +2765,7 @@ fixed_pointer_initializer | expression ; -// Source: §23.8.2 Fixed-size buffer declarations +// Source: §24.8.2 Fixed-size buffer declarations fixed_size_buffer_declaration : attributes? fixed_size_buffer_modifier* 'fixed' buffer_element_type fixed_size_buffer_declarators ';' diff --git a/standard/interfaces.md b/standard/interfaces.md index 0ea1090e6..bdb9add3b 100644 --- a/standard/interfaces.md +++ b/standard/interfaces.md @@ -1,14 +1,14 @@ -# 18 Interfaces +# 19 Interfaces -## 18.1 General +## 19.1 General An interface defines a contract. A class or struct that implements an interface shall adhere to its contract. An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces. Interfaces can contain methods, properties, events, and indexers. The interface itself does not provide implementations for the members that it declares. The interface merely specifies the members that shall be supplied by classes or structs that implement the interface. -## 18.2 Interface declarations +## 19.2 Interface declarations -### 18.2.1 General +### 19.2.1 General An *interface_declaration* is a *type_declaration* ([§14.7](namespaces.md#147-type-declarations)) that declares a new interface type. @@ -20,13 +20,13 @@ interface_declaration ; ``` -An *interface_declaration* consists of an optional set of *attributes* ([§22](attributes.md#22-attributes)), followed by an optional set of *interface_modifier*s ([§18.2.2](interfaces.md#1822-interface-modifiers)), followed by an optional partial modifier ([§15.2.7](classes.md#1527-partial-type-declarations)), followed by the keyword `interface` and an *identifier* that names the interface, followed by an optional *variant_type_parameter_list* specification ([§18.2.3](interfaces.md#1823-variant-type-parameter-lists)), followed by an optional *interface_base* specification ([§18.2.4](interfaces.md#1824-base-interfaces)), followed by an optional *type_parameter_constraints_clause*s specification ([§15.2.5](classes.md#1525-type-parameter-constraints)), followed by an *interface_body* ([§18.3](interfaces.md#183-interface-body)), optionally followed by a semicolon. +An *interface_declaration* consists of an optional set of *attributes* ([§23](attributes.md#23-attributes)), followed by an optional set of *interface_modifier*s ([§19.2.2](interfaces.md#1922-interface-modifiers)), followed by an optional partial modifier ([§15.2.7](classes.md#1527-partial-type-declarations)), followed by the keyword `interface` and an *identifier* that names the interface, followed by an optional *variant_type_parameter_list* specification ([§19.2.3](interfaces.md#1923-variant-type-parameter-lists)), followed by an optional *interface_base* specification ([§19.2.4](interfaces.md#1924-base-interfaces)), followed by an optional *type_parameter_constraints_clause*s specification ([§15.2.5](classes.md#1525-type-parameter-constraints)), followed by an *interface_body* ([§19.3](interfaces.md#193-interface-body)), optionally followed by a semicolon. An interface declaration shall not supply *type_parameter_constraints_clause*s unless it also supplies a *variant_type_parameter_list*. An interface declaration that supplies a *variant_type_parameter_list* is a generic interface declaration. Additionally, any interface nested inside a generic class declaration or a generic struct declaration is itself a generic interface declaration, since type arguments for the containing type shall be supplied to create a constructed type ([§8.4](types.md#84-constructed-types)). -### 18.2.2 Interface modifiers +### 19.2.2 Interface modifiers An *interface_declaration* may optionally include a sequence of interface modifiers: @@ -41,7 +41,7 @@ interface_modifier ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). It is a compile-time error for the same modifier to appear multiple times in an interface declaration. @@ -49,9 +49,9 @@ The `new` modifier is only permitted on interfaces defined within a class. It sp The `public`, `protected`, `internal`, and `private` modifiers control the accessibility of the interface. Depending on the context in which the interface declaration occurs, only some of these modifiers might be permitted ([§7.5.2](basic-concepts.md#752-declared-accessibility)). When a partial type declaration ([§15.2.7](classes.md#1527-partial-type-declarations)) includes an accessibility specification (via the `public`, `protected`, `internal`, and `private` modifiers), the rules in [§15.2.2](classes.md#1522-class-modifiers) apply. -### 18.2.3 Variant type parameter lists +### 19.2.3 Variant type parameter lists -#### 18.2.3.1 General +#### 19.2.3.1 General Variant type parameter lists can only occur on interface and delegate types. The difference from ordinary *type_parameter_list*s is the optional *variance_annotation* on each type parameter. @@ -89,7 +89,7 @@ If the variance annotation is `out`, the type parameter is said to be ***covaria If a generic interface is declared in multiple parts ([§15.2.3](classes.md#1523-type-parameters)), each partial declaration shall specify the same variance for each type parameter. -#### 18.2.3.2 Variance safety +#### 19.2.3.2 Variance safety The occurrence of variance annotations in the type parameter list of a type restricts the places where types can occur within the type declaration. @@ -113,7 +113,7 @@ Intuitively, an output-unsafe type is prohibited in an output position, and an i A type is ***output-safe*** if it is not output-unsafe, and ***input-safe*** if it is not input-unsafe. -#### 18.2.3.3 Variance conversion +#### 19.2.3.3 Variance conversion The purpose of variance annotations is to provide for more lenient (but still type safe) conversions to interface and delegate types. To this end the definitions of implicit ([§10.2](conversions.md#102-implicit-conversions)) and explicit conversions ([§10.3](conversions.md#103-explicit-conversions)) make use of the notion of variance-convertibility, which is defined as follows: @@ -123,7 +123,7 @@ A type `T` is variance-convertible to a type `T *Note*: The members in class `object` are not, strictly speaking, members of any interface ([§18.4](interfaces.md#184-interface-members)). However, the members in class `object` are available via member lookup in any interface type ([§12.5](expressions.md#125-member-lookup)). *end note* +> *Note*: The members in class `object` are not, strictly speaking, members of any interface ([§19.4](interfaces.md#194-interface-members)). However, the members in class `object` are available via member lookup in any interface type ([§12.5](expressions.md#125-member-lookup)). *end note* The set of members of an interface declared in multiple parts ([§15.2.7](classes.md#1527-partial-type-declarations)) is the union of the members declared in each part. The bodies of all parts of the interface declaration share the same declaration space ([§7.3](basic-concepts.md#73-declarations)), and the scope of each member ([§7.7](basic-concepts.md#77-scopes)) extends to the bodies of all the parts. -### 18.4.2 Interface methods +### 19.4.2 Interface methods Interface methods are declared using *interface_method_declaration*s: @@ -261,7 +261,7 @@ interface_method_header The *attributes*, *return_type*, *ref_return_type*, *identifier*, and *parameter_list* of an interface method declaration have the same meaning as those of a method declaration in a class ([§15.6](classes.md#156-methods)). An interface method declaration is not permitted to specify a method body, and the declaration therefore always ends with a semicolon. -All parameter types of an interface method shall be input-safe ([§18.2.3.2](interfaces.md#18232-variance-safety)), and the return type shall be either `void` or output-safe. In addition, any output or reference parameter types shall also be output-safe. +All parameter types of an interface method shall be input-safe ([§19.2.3.2](interfaces.md#19232-variance-safety)), and the return type shall be either `void` or output-safe. In addition, any output or reference parameter types shall also be output-safe. > *Note*: Output parameters are required to be input-safe due to common implementation restrictions. *end note* @@ -306,7 +306,7 @@ These rules ensure that any covariant or contravariant usage of the interface re > > *end example* -### 18.4.3 Interface properties +### 19.4.3 Interface properties Interface properties are declared using *interface_property_declaration*s: @@ -334,7 +334,7 @@ The accessors of an interface property declaration correspond to the accessors o The type of an interface property shall be output-safe if there is a get accessor, and shall be input-safe if there is a set accessor. -### 18.4.4 Interface events +### 19.4.4 Interface events Interface events are declared using *interface_event_declaration*s: @@ -348,7 +348,7 @@ The *attributes*, *type*, and *identifier* of an interface event declaration hav The type of an interface event shall be input-safe. -### 18.4.5 Interface indexers +### 19.4.5 Interface indexers Interface indexers are declared using *interface_indexer_declaration*s: @@ -365,17 +365,17 @@ The *attributes*, *type*, and *parameter_list* of an interface indexer declarati The accessors of an interface indexer declaration correspond to the accessors of a class indexer declaration ([§15.9](classes.md#159-indexers)), except that the *accessor_body* shall always be a semicolon. Thus, the accessors simply indicate whether the indexer is read-write, read-only, or write-only. -All the parameter types of an interface indexer shall be input-safe ([§18.2.3.2](interfaces.md#18232-variance-safety)). In addition, any output or reference parameter types shall also be output-safe. +All the parameter types of an interface indexer shall be input-safe ([§19.2.3.2](interfaces.md#19232-variance-safety)). In addition, any output or reference parameter types shall also be output-safe. > *Note*: Output parameters are required to be input-safe due to common implementation restrictions. *end note* The type of an interface indexer shall be output-safe if there is a get accessor, and shall be input-safe if there is a set accessor. -### 18.4.6 Interface member access +### 19.4.6 Interface member access -Interface members are accessed through member access ([§12.8.7](expressions.md#1287-member-access)) and indexer access ([§12.8.12.3](expressions.md#128123-indexer-access)) expressions of the form `I.M` and `I[A]`, where `I` is an interface type, `M` is a method, property, or event of that interface type, and `A` is an indexer argument list. +Interface members are accessed through member access ([§12.8.7](expressions.md#1287-member-access)) and indexer access ([§12.8.12.4](expressions.md#128124-indexer-access)) expressions of the form `I.M` and `I[A]`, where `I` is an interface type, `M` is a method, property, or event of that interface type, and `A` is an indexer argument list. -For interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effects of the member lookup ([§12.5](expressions.md#125-member-lookup)), method invocation ([§12.8.10.2](expressions.md#128102-method-invocations)), and indexer access ([§12.8.12.3](expressions.md#128123-indexer-access)) rules are exactly the same as for classes and structs: More derived members hide less derived members with the same name or signature. However, for multiple-inheritance interfaces, ambiguities can occur when two or more unrelated base interfaces declare members with the same name or signature. This subclause shows several examples, some of which lead to ambiguities and others which don’t. In all cases, explicit casts can be used to resolve the ambiguities. +For interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effects of the member lookup ([§12.5](expressions.md#125-member-lookup)), method invocation ([§12.8.10.2](expressions.md#128102-method-invocations)), and indexer access ([§12.8.12.4](expressions.md#128124-indexer-access)) rules are exactly the same as for classes and structs: More derived members hide less derived members with the same name or signature. However, for multiple-inheritance interfaces, ambiguities can occur when two or more unrelated base interfaces declare members with the same name or signature. This subclause shows several examples, some of which lead to ambiguities and others which don’t. In all cases, explicit casts can be used to resolve the ambiguities. > *Example*: In the following code > @@ -483,7 +483,7 @@ For interfaces that are strictly single-inheritance (each interface in the inher > > *end example* -## 18.5 Qualified interface member names +## 19.5 Qualified interface member names An interface member is sometimes referred to by its ***qualified interface member name***. The qualified name of an interface member consists of the name of the interface in which the member is declared, followed by a dot, followed by the name of the member. The qualified name of a member references the interface in which the member is declared. @@ -525,9 +525,9 @@ When an interface is part of a namespace, a qualified interface member name can > > *end example* -## 18.6 Interface implementations +## 19.6 Interface implementations -### 18.6.1 General +### 19.6.1 General Interfaces may be implemented by classes and structs. To indicate that a class or struct directly implements an interface, the interface is included in the base class list of the class or struct. @@ -583,7 +583,7 @@ A class or struct that directly implements an interface also implicitly implemen When a class `C` directly implements an interface, all classes derived from `C` also implement the interface implicitly. -The base interfaces specified in a class declaration can be constructed interface types ([§8.4](types.md#84-constructed-types), [§18.2](interfaces.md#182-interface-declarations)). +The base interfaces specified in a class declaration can be constructed interface types ([§8.4](types.md#84-constructed-types), [§19.2](interfaces.md#192-interface-declarations)). > *Example*: The following code illustrates how a class can implement constructed interface types: > @@ -597,9 +597,9 @@ The base interfaces specified in a class declaration can be constructed interfac > > *end example* -The base interfaces of a generic class declaration shall satisfy the uniqueness rule described in [§18.6.3](interfaces.md#1863-uniqueness-of-implemented-interfaces). +The base interfaces of a generic class declaration shall satisfy the uniqueness rule described in [§19.6.3](interfaces.md#1963-uniqueness-of-implemented-interfaces). -### 18.6.2 Explicit interface member implementations +### 19.6.2 Explicit interface member implementations For purposes of implementing interfaces, a class or struct may declare ***explicit interface member implementations***. An explicit interface member implementation is a method, property, event, or indexer declaration that references a qualified interface member name. @@ -755,7 +755,7 @@ The qualified interface member name of an explicit interface member implementati > > *end example* -### 18.6.3 Uniqueness of implemented interfaces +### 19.6.3 Uniqueness of implemented interfaces The interfaces implemented by a generic type declaration shall remain unique for all possible constructed types. Without this rule, it would be impossible to determine the correct method to call for certain constructed types. @@ -820,9 +820,9 @@ I x = new Derived(); x.F(); ``` -invokes the method in `Derived`, since `Derived'` effectively re-implements `I` ([§18.6.7](interfaces.md#1867-interface-re-implementation)). +invokes the method in `Derived`, since `Derived'` effectively re-implements `I` ([§19.6.7](interfaces.md#1967-interface-re-implementation)). -### 18.6.4 Implementation of generic methods +### 19.6.4 Implementation of generic methods When a generic method implicitly implements an interface method, the constraints given for each method type parameter shall be equivalent in both declarations (after any interface type parameters are replaced with the appropriate type arguments), where method type parameters are identified by ordinal positions, left to right. @@ -868,9 +868,9 @@ When a generic method implicitly implements an interface method, the constraints -> *Note*: When a generic method explicitly implements an interface method no constraints are allowed on the implementing method ([§15.7.1](classes.md#1571-general), [§18.6.2](interfaces.md#1862-explicit-interface-member-implementations)). *end note* +> *Note*: When a generic method explicitly implements an interface method no constraints are allowed on the implementing method ([§15.7.1](classes.md#1571-general), [§19.6.2](interfaces.md#1962-explicit-interface-member-implementations)). *end note* -### 18.6.5 Interface mapping +### 19.6.5 Interface mapping A class or struct shall provide implementations of all members of the interfaces that are listed in the base class list of the class or struct. The process of locating implementations of interface members in an implementing class or struct is known as ***interface mapping***. @@ -1062,7 +1062,7 @@ The members of a base class participate in interface mapping. > > *end example* -### 18.6.6 Interface implementation inheritance +### 19.6.6 Interface implementation inheritance A class inherits all interface implementations provided by its base classes. @@ -1171,7 +1171,7 @@ Since explicit interface member implementations cannot be declared virtual, it i > > *end example* -### 18.6.7 Interface re-implementation +### 19.6.7 Interface re-implementation A class that inherits an interface implementation is permitted to ***re-implement*** the interface by including it in the base class list. @@ -1267,7 +1267,7 @@ When a class implements an interface, it implicitly also implements all that int > > *end example* -### 18.6.8 Abstract classes and interfaces +### 19.6.8 Abstract classes and interfaces Like a non-abstract class, an abstract class shall provide implementations of all members of the interfaces that are listed in the base class list of the class. However, an abstract class is permitted to map interface methods onto abstract methods. diff --git a/standard/lexical-structure.md b/standard/lexical-structure.md index f440da104..83b4bec65 100644 --- a/standard/lexical-structure.md +++ b/standard/lexical-structure.md @@ -59,7 +59,7 @@ The productions for: - *null_conditional_member_access* ([§12.8.8](expressions.md#1288-null-conditional-member-access)), - *dependent_access* ([§12.8.8](expressions.md#1288-null-conditional-member-access)), - *base_access* ([§12.8.15](expressions.md#12815-base-access)) and -- *pointer_member_access* ([§23.6.3](unsafe-code.md#2363-pointer-member-access)); +- *pointer_member_access* ([§24.6.3](unsafe-code.md#2463-pointer-member-access)); (the “disambiguated productions”) can give rise to ambiguities in the grammar for expressions. @@ -134,7 +134,7 @@ then the *type_argument_list* shall be retained as part of the disambiguated pro > > *end example* -When recognising a *relational_expression* ([§12.12.1](expressions.md#12121-general)) if both the “*relational_expression* `is` *type*” and “*relational_expression* `is` *pattern*” alternatives are applicable, and *type* resolves to an accessible type, then the “*relational_expression* `is` *type*” alternative shall be chosen. +When recognising a *relational_expression* ([§12.13.1](expressions.md#12131-general)) if both the “*relational_expression* `is` *type*” and “*relational_expression* `is` *pattern*” alternatives are applicable, and *type* resolves to an accessible type, then the “*relational_expression* `is` *type*” alternative shall be chosen. ## 6.3 Lexical analysis @@ -616,7 +616,7 @@ In most cases, the syntactic location of contextual keywords is such that they c In certain cases the grammar is not enough to distinguish contextual keyword usage from identifiers. In all such cases it will be specified how to disambiguate between the two. For example, the contextual keyword `var` in implicitly typed local variable declarations ([§13.6.2](statements.md#1362-local-variable-declarations)) might conflict with a declared type called `var`, in which case the declared name takes precedence over the use of the identifier as a contextual keyword. -Another example such disambiguation is the contextual keyword `await` ([§12.9.8.1](expressions.md#12981-general)), which is considered a keyword only when inside a method declared `async`, but can be used as an identifier elsewhere. +Another example such disambiguation is the contextual keyword `await` ([§12.9.9.1](expressions.md#12991-general)), which is considered a keyword only when inside a method declared `async`, but can be used as an identifier elsewhere. Just as with keywords, contextual keywords can be used as ordinary identifiers by prefixing them with the `@` character. @@ -967,7 +967,7 @@ fragment Quote_Escape_Sequence The type of a *String_Literal* is `string`. -Each string literal does not necessarily result in a new string instance. When two or more string literals that are equivalent according to the string equality operator ([§12.12.8](expressions.md#12128-string-equality-operators)), appear in the same assembly, these string literals refer to the same string instance. +Each string literal does not necessarily result in a new string instance. When two or more string literals that are equivalent according to the string equality operator ([§12.13.8](expressions.md#12138-string-equality-operators)), appear in the same assembly, these string literals refer to the same string instance. > *Example*: For instance, the output produced by > @@ -1195,7 +1195,7 @@ fragment PP_Primary_Expression When referenced in a pre-processing expression, a defined conditional compilation symbol has the Boolean value `true`, and an undefined conditional compilation symbol has the Boolean value `false`. -Evaluation of a pre-processing expression always yields a Boolean value. The rules of evaluation for a pre-processing expression are the same as those for a constant expression ([§12.23](expressions.md#1223-constant-expressions)), except that the only user-defined entities that can be referenced are conditional compilation symbols. +Evaluation of a pre-processing expression always yields a Boolean value. The rules of evaluation for a pre-processing expression are the same as those for a constant expression ([§12.24](expressions.md#1224-constant-expressions)), except that the only user-defined entities that can be referenced are conditional compilation symbols. ### 6.5.4 Definition directives @@ -1483,7 +1483,7 @@ corresponds exactly to the lexical processing of a conditional compilation direc ### 6.5.8 Line directives -Line directives may be used to alter the line numbers and compilation unit names that are reported by a compiler in output such as warnings and errors. These values are also used by caller-info attributes ([§22.5.6](attributes.md#2256-caller-info-attributes)). +Line directives may be used to alter the line numbers and compilation unit names that are reported by a compiler in output such as warnings and errors. These values are also used by caller-info attributes ([§23.5.6](attributes.md#2356-caller-info-attributes)). > *Note*: Line directives are most commonly used in meta-programming tools that generate C# source code from some other text input. *end note* @@ -1515,7 +1515,7 @@ The maximum value allowed for `Decimal_Digit+` is implementation-defined. A `#line default` directive undoes the effect of all preceding `#line` directives. A compiler reports true line information for subsequent lines, precisely as if no `#line` directives had been processed. -A `#line hidden` directive has no effect on the compilation unit and line numbers reported in error messages, or produced by use of `CallerLineNumberAttribute` ([§22.5.6.2](attributes.md#22562-the-callerlinenumber-attribute)). It is intended to affect source-level debugging tools so that, when debugging, all lines between a `#line hidden` directive and the subsequent `#line` directive (that is not `#line hidden`) have no line number information, and are skipped entirely when stepping through code. +A `#line hidden` directive has no effect on the compilation unit and line numbers reported in error messages, or produced by use of `CallerLineNumberAttribute` ([§23.5.6.2](attributes.md#23562-the-callerlinenumber-attribute)). It is intended to affect source-level debugging tools so that, when debugging, all lines between a `#line hidden` directive and the subsequent `#line` directive (that is not `#line hidden`) have no line number information, and are skipped entirely when stepping through code. > *Note*: Although a *PP_Compilation_Unit_Name* might contain text that looks like an escape sequence, such text is not an escape sequence; in this context a ‘`\`’ character simply designates an ordinary backslash character. *end note* diff --git a/standard/namespaces.md b/standard/namespaces.md index b0f5bdbc8..7abbb06db 100644 --- a/standard/namespaces.md +++ b/standard/namespaces.md @@ -23,7 +23,7 @@ The *extern_alias_directive*s of a compilation unit affect the *using_directive* The *using_directive*s of a compilation unit affect the *global_attributes* and *namespace_member_declaration*s of that compilation unit, but have no effect on other compilation units. -The *global_attributes* ([§22.3](attributes.md#223-attribute-specification)) of a compilation unit permit the specification of attributes for the target assembly and module. Assemblies and modules act as physical containers for types. An assembly may consist of several physically separate modules. +The *global_attributes* ([§23.3](attributes.md#233-attribute-specification)) of a compilation unit permit the specification of attributes for the target assembly and module. Assemblies and modules act as physical containers for types. An assembly may consist of several physically separate modules. The *namespace_member_declaration*s of each compilation unit of a program contribute members to a single declaration space called the global namespace. @@ -754,7 +754,7 @@ A compilation unit or a namespace body can contain *namespace_member_declaration ## 14.7 Type declarations -A *type_declaration* is a *class_declaration* ([§15.2](classes.md#152-class-declarations)), a *struct_declaration* ([§16.2](structs.md#162-struct-declarations)), an *interface_declaration* ([§18.2](interfaces.md#182-interface-declarations)), an *enum_declaration* ([§19.2](enums.md#192-enum-declarations)), or a *delegate_declaration* ([§20.2](delegates.md#202-delegate-declarations)). +A *type_declaration* is a *class_declaration* ([§15.2](classes.md#152-class-declarations)), a *struct_declaration* ([§16.2](structs.md#162-struct-declarations)), an *interface_declaration* ([§19.2](interfaces.md#192-interface-declarations)), an *enum_declaration* ([§20.2](enums.md#202-enum-declarations)), or a *delegate_declaration* ([§21.2](delegates.md#212-delegate-declarations)). ```ANTLR type_declaration diff --git a/standard/patterns.md b/standard/patterns.md index 68a2ea216..2fa88352a 100644 --- a/standard/patterns.md +++ b/standard/patterns.md @@ -2,7 +2,7 @@ ## 11.1 General -A ***pattern*** is a syntactic form that can be used with the `is` operator ([§12.12.12](expressions.md#121212-the-is-operator)) and in a *switch_statement* ([§13.8.3](statements.md#1383-the-switch-statement)) to express the shape of data against which incoming data is to be compared. A pattern is tested against the *expression* of a switch statement, or against a *relational_expression* that is on the left-hand side of an `is` operator, each of which is referred to as a ***pattern input value***. +A ***pattern*** is a syntactic form that can be used with the `is` operator ([§12.13.12](expressions.md#121312-the-is-operator)) and in a *switch_statement* ([§13.8.3](statements.md#1383-the-switch-statement)) to express the shape of data against which incoming data is to be compared. A pattern is tested against the *expression* of a switch statement, or against a *relational_expression* that is on the left-hand side of an `is` operator, each of which is referred to as a ***pattern input value***. ## 11.2 Pattern forms @@ -64,7 +64,7 @@ single_variable_designation ; ``` -The runtime type of the value is tested against the *type* in the pattern using the same rules specified in the is-type operator ([§12.12.12.1](expressions.md#1212121-the-is-type-operator)). If the test succeeds, the pattern *matches* that value. It is a compile-time error if the *type* is a nullable value type ([§8.3.12](types.md#8312-nullable-value-types)). This pattern form never matches a `null` value. +The runtime type of the value is tested against the *type* in the pattern using the same rules specified in the is-type operator ([§12.13.12.1](expressions.md#1213121-the-is-type-operator)). If the test succeeds, the pattern *matches* that value. It is a compile-time error if the *type* is a nullable value type ([§8.3.12](types.md#8312-nullable-value-types)). This pattern form never matches a `null` value. > *Note*: The is-type expression `e is T` and the declaration pattern `e is T _` are equivalent when `T` isn’t a nullable type. *end note* diff --git a/standard/portability-issues.md b/standard/portability-issues.md index 1704cfb4f..823b0f8ac 100644 --- a/standard/portability-issues.md +++ b/standard/portability-issues.md @@ -10,12 +10,12 @@ This annex collects some information about portability that appears in this spec The behavior is undefined in the following circumstances: -1. The behavior of the enclosing async function when an awaiter’s implementation of the interface methods `INotifyCompletion.OnCompleted` and `ICriticalNotifyCompletion.UnsafeOnCompleted` does not cause the resumption delegate to be invoked at most once ([§12.9.8.4](expressions.md#12984-run-time-evaluation-of-await-expressions)). -1. Passing pointers as reference or output parameters ([§23.3](unsafe-code.md#233-pointer-types)). -1. When dereferencing the result of converting one pointer type to another and the resulting pointer is not correctly aligned for the pointed-to type. ([§23.5.1](unsafe-code.md#2351-general)). -1. When the unary `*` operator is applied to a pointer containing an invalid value ([§23.6.2](unsafe-code.md#2362-pointer-indirection)). -1. When a pointer is subscripted to access an out-of-bounds element ([§23.6.4](unsafe-code.md#2364-pointer-element-access)). -1. Modifying objects of managed type through fixed pointers ([§23.7](unsafe-code.md#237-the-fixed-statement)). +1. The behavior of the enclosing async function when an awaiter’s implementation of the interface methods `INotifyCompletion.OnCompleted` and `ICriticalNotifyCompletion.UnsafeOnCompleted` does not cause the resumption delegate to be invoked at most once ([§12.9.9.4](expressions.md#12994-run-time-evaluation-of-await-expressions)). +1. Passing pointers as reference or output parameters ([§24.3](unsafe-code.md#243-pointer-types)). +1. When dereferencing the result of converting one pointer type to another and the resulting pointer is not correctly aligned for the pointed-to type. ([§24.5.1](unsafe-code.md#2451-general)). +1. When the unary `*` operator is applied to a pointer containing an invalid value ([§24.6.2](unsafe-code.md#2462-pointer-indirection)). +1. When a pointer is subscripted to access an out-of-bounds element ([§24.6.4](unsafe-code.md#2464-pointer-element-access)). +1. Modifying objects of managed type through fixed pointers ([§24.7](unsafe-code.md#247-the-fixed-statement)). 1. The content of memory newly allocated by `stackalloc` ([§12.8.22](expressions.md#12822-stack-allocation)). 1. Attempting to allocate a negative number of items using `stackalloc`([§12.8.22](expressions.md#12822-stack-allocation)). 1. Implicit dynamic conversions ([§10.2.10](conversions.md#10210-implicit-dynamic-conversions)) of input parameters with value arguments ([§12.6.4.2](expressions.md#12642-applicable-function-member)). @@ -39,18 +39,18 @@ A conforming implementation is required to document its choice of behavior in ea 1. The precise structure of the expression tree, as well as the exact process for creating it, when an anonymous function is converted to an expression-tree. ([§10.7.3](conversions.md#1073-evaluation-of-lambda-expression-conversions-to-expression-tree-types)) 1. The reason a conversion to a compatible delegate type may fail at compile-time. ([§10.7.3](conversions.md#1073-evaluation-of-lambda-expression-conversions-to-expression-tree-types)) 1. The value returned when a stack allocation of size zero is made. ([§12.8.22](expressions.md#12822-stack-allocation)) -1. Whether a `System.ArithmeticException` (or a subclass thereof) is thrown or the overflow goes unreported with the resulting value being that of the left operand, when in an `unchecked` context and the left operand of an integer division is the maximum negative `int` or `long` value and the right operand is `–1`. ([§12.10.3](expressions.md#12103-division-operator)) -1. When a `System.ArithmeticException` (or a subclass thereof) is thrown when performing a decimal remainder operation. ([§12.10.4](expressions.md#12104-remainder-operator)) +1. Whether a `System.ArithmeticException` (or a subclass thereof) is thrown or the overflow goes unreported with the resulting value being that of the left operand, when in an `unchecked` context and the left operand of an integer division is the maximum negative `int` or `long` value and the right operand is `–1`. ([§12.11.3](expressions.md#12113-division-operator)) +1. When a `System.ArithmeticException` (or a subclass thereof) is thrown when performing a decimal remainder operation. ([§12.11.4](expressions.md#12114-remainder-operator)) 1. The impact of thread termination when a thread has no handler for an exception, and the thread is itself terminated. ([§13.10.6](statements.md#13106-the-throw-statement)) 1. The mechanism by which linkage to an external method is achieved. ([§15.6.8](classes.md#1568-external-methods)) -1. The impact of thread termination when no matching `catch` clause is found for an exception and the code that initially started that thread is reached. ([§21.4](exceptions.md#214-how-exceptions-are-handled)). -1. An execution environment may provide additional attributes that affect the execution of a C# program. ([§22.5.1](attributes.md#2251-general)) -1. The mappings between pointers and integers. ([§23.5.1](unsafe-code.md#2351-general)) -1. The effect of applying the unary `*` operator to a `null` pointer. ([§23.6.2](unsafe-code.md#2362-pointer-indirection)) -1. The behavior when pointer arithmetic overflows the domain of the pointer type. ([§23.6.6](unsafe-code.md#2366-pointer-increment-and-decrement), [§23.6.7](unsafe-code.md#2367-pointer-arithmetic)) -1. The result of the `sizeof` operator for non-pre-defined value types. ([§23.6.9](unsafe-code.md#2369-the-sizeof-operator)) -1. The behavior of the `fixed` statement if the array expression is `null` or if the array has zero elements. ([§23.7](unsafe-code.md#237-the-fixed-statement)) -1. The behavior of the `fixed` statement if the string expression is `null`. ([§23.7](unsafe-code.md#237-the-fixed-statement)) +1. The impact of thread termination when no matching `catch` clause is found for an exception and the code that initially started that thread is reached. ([§22.4](exceptions.md#224-how-exceptions-are-handled)). +1. An execution environment may provide additional attributes that affect the execution of a C# program. ([§23.5.1](attributes.md#2351-general)) +1. The mappings between pointers and integers. ([§24.5.1](unsafe-code.md#2451-general)) +1. The effect of applying the unary `*` operator to a `null` pointer. ([§24.6.2](unsafe-code.md#2462-pointer-indirection)) +1. The behavior when pointer arithmetic overflows the domain of the pointer type. ([§24.6.6](unsafe-code.md#2466-pointer-increment-and-decrement), [§24.6.7](unsafe-code.md#2467-pointer-arithmetic)) +1. The result of the `sizeof` operator for non-pre-defined value types. ([§24.6.9](unsafe-code.md#2469-the-sizeof-operator)) +1. The behavior of the `fixed` statement if the array expression is `null` or if the array has zero elements. ([§24.7](unsafe-code.md#247-the-fixed-statement)) +1. The behavior of the `fixed` statement if the string expression is `null`. ([§24.7](unsafe-code.md#247-the-fixed-statement)) ## B.4 Unspecified behavior @@ -59,15 +59,15 @@ A conforming implementation is required to document its choice of behavior in ea 1. The value of the result when converting out-of-range values from `float` or `double` values to an integral type in an `unchecked` context ([§10.3.2](conversions.md#1032-explicit-numeric-conversions)). 1. The exact target object and target method of the delegate produced from an *anonymous_method_expression* contains ([§10.7.2](conversions.md#1072-evaluation-of-anonymous-function-conversions-to-delegate-types)). 1. The layout of arrays, except in an unsafe context ([§12.8.17.4](expressions.md#128174-array-creation-expressions)). -1. Whether there is any way to execute the *block* of an anonymous function other than through evaluation and invocation of the *lambda_expression* or *anonymous_method-expression* ([§12.19.3](expressions.md#12193-anonymous-function-bodies)). +1. Whether there is any way to execute the *block* of an anonymous function other than through evaluation and invocation of the *lambda_expression* or *anonymous_method-expression* ([§12.20.3](expressions.md#12203-anonymous-function-bodies)). 1. The exact timing of static field initialization ([§15.5.6.2](classes.md#15562-static-field-initialization)). 1. The result of invoking `MoveNext` when an enumerator object is running ([§15.15.5.2](classes.md#151552-advance-the-enumerator)). 1. The result of accessing `Current` when an enumerator object is in the before, running, or after states ([§15.15.5.3](classes.md#151553-retrieve-the-current-value)). 1. The result of invoking `Dispose` when an enumerator object is in the running state ([§15.15.5.4](classes.md#151554-dispose-of-resources)). -1. The attributes of a type declared in multiple parts are determined by combining, in an unspecified order, the attributes of each of its parts ([§22.3](attributes.md#223-attribute-specification)). -1. The order in which members are packed into a struct ([§23.6.9](unsafe-code.md#2369-the-sizeof-operator)). -1. An exception occurs during finalizer execution, and that exception is not caught ([§21.4](exceptions.md#214-how-exceptions-are-handled)). -1. If more than one member matches, which member is the implementation of `I.M` ([§18.6.5](interfaces.md#1865-interface-mapping)). +1. The attributes of a type declared in multiple parts are determined by combining, in an unspecified order, the attributes of each of its parts ([§23.3](attributes.md#233-attribute-specification)). +1. The order in which members are packed into a struct ([§24.6.9](unsafe-code.md#2469-the-sizeof-operator)). +1. An exception occurs during finalizer execution, and that exception is not caught ([§22.4](exceptions.md#224-how-exceptions-are-handled)). +1. If more than one member matches, which member is the implementation of `I.M` ([§19.6.5](interfaces.md#1965-interface-mapping)). ## B.5 Other issues diff --git a/standard/ranges.md b/standard/ranges.md index c9ce08b24..a5b65c28b 100644 --- a/standard/ranges.md +++ b/standard/ranges.md @@ -1,13 +1,13 @@ -# 24 Extended indexing and slicing +# 18 Extended indexing and slicing -> **Review Note:** This new clause, currently (§24), is placed here temporarily to avoid text changes due to renumbering occurring in chapters & clauses otherwise unaffected by the PR. Its final placement is not yet determined, however between the Arrays ([§17](arrays.md#17-arrays)) and Interfaces ([§18](interfaces.md#18-interfaces)) chapters might be suitable – other placements can be suggested during review. It can be relocated later with just a simple edit to `clauses.json`. +> **Review Note:** This new clause, currently ([§18](ranges.md#18-extended-indexing-and-slicing)), is placed here temporarily to avoid text changes due to renumbering occurring in chapters & clauses otherwise unaffected by the PR. Its final placement is not yet determined, however between the Arrays ([§17](arrays.md#17-arrays)) and Interfaces ([§19](interfaces.md#19-interfaces)) chapters might be suitable – other placements can be suggested during review. It can be relocated later with just a simple edit to `clauses.json`. -## 24.1 General +## 18.1 General This clause introduces a model for *extended indexable* and *sliceable* *collection* types built on: -- The types introduced in this clause, `System.Index` (§24.2) and `System.Range` (§24.3); -- The pre-defined unary `^` (§hat-operator) and binary `..` (§range-operator) operators; and +- The types introduced in this clause, `System.Index` ([§18.2](ranges.md#182-the-index-type)) and `System.Range` ([§18.3](ranges.md#183-the-range-type)); +- The pre-defined unary `^` ([§12.9.6](expressions.md#1296-hat-operator)) and binary `..` ([§12.10](expressions.md#1210-range-operator)) operators; and - The *element_access* expression. Under the model a type is classified as: @@ -18,11 +18,11 @@ Under the model a type is classified as: > *Note*: The model does not require that a slice of the type can be set, but a type may support it as an extension of the model. *end note* -The model is supported for single-dimensional arrays (§12.8.12.2) and strings (§string-access). +The model is supported for single-dimensional arrays ([§12.8.12.2](expressions.md#128122-array-access)) and strings ([§12.8.12.3](expressions.md#128123-string-access)). -The model can be supported by any class, struct or interface type which provides appropriate indexers (§15.9) which implement the model semantics. +The model can be supported by any class, struct or interface type which provides appropriate indexers ([§15.9](classes.md#159-indexers)) which implement the model semantics. -Implicit support for the model is provided for types which do not directly support it but which provide a certain *pattern* of members (§24.4). This support is pattern-based, rather than semantic-based, as the semantics of the type members upon which it is based are *assumed* – the language does not enforce, or check, the semantics of these type members. +Implicit support for the model is provided for types which do not directly support it but which provide a certain *pattern* of members ([§18.4](ranges.md#184-pattern-based-implicit-support-for-index-and-range)). This support is pattern-based, rather than semantic-based, as the semantics of the type members upon which it is based are *assumed* – the language does not enforce, or check, the semantics of these type members. For the purposes of this clause the following terms are defined: @@ -47,7 +47,7 @@ The above definitions are extended for uses of `Index` and `Range` as follows: - A type is also a *sequence* if an *element_access* expression taking a single required `Index` argument, rather than an `int` argument, is supported. Where a distinction is required the type is termed ***extended indexable***. - A type is also *sliceable* if an *element_access* expression taking a single required `Range` argument, rather a `Slice` method, is supported. Where a distinction is required the type is termed ***extended sliceable***. -Whether a type is classified as countable, indexable, or sliceable is subject to the constraints of member accessibility (§7.5) and therefore dependent on where the type is being used. +Whether a type is classified as countable, indexable, or sliceable is subject to the constraints of member accessibility ([§7.5](basic-concepts.md#75-member-access)) and therefore dependent on where the type is being used. > *Example*: A type where the countable property and/or the indexer are `protected` is only a sequence to members of itself and any derived types. *end example* @@ -86,7 +86,7 @@ The required members for a type to qualify as a sequence or sliceable may be inh > > *end note* -## 24.2 The Index type +## 18.2 The Index type The `System.Index` type represents an *abstract* index which is either a *from-start index* or a *from-end index*. @@ -118,7 +118,7 @@ The `System.Index` type represents an *abstract* index which is either a *from-s > > *end example* -There is an implicit conversion from `int` to `Index` which produces from-start indices, and a language-defined unary operator `^` (§hat-operator) from `int` to `Index` which produces from-end indices. +There is an implicit conversion from `int` to `Index` which produces from-start indices, and a language-defined unary operator `^` ([§12.9.6](expressions.md#1296-hat-operator)) from `int` to `Index` which produces from-end indices. > *Example* > @@ -142,14 +142,14 @@ This method does **not** check that the return value is in the valid range of `0 > *Note:* `Index` values are unordered as they are abstract indices, it is in general impossible to determine whether a from-end index comes before or after a from start index without reference to a sequence length. Once converted to concrete indices, e.g. by `GetOffset`, those concrete indices are comparable. *end note* -`Index` values may be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: +`Index` values may be directly used in the *argument_list* of an *element_access* expression ([§12.8.12](expressions.md#12812-element-access)) which is: -- an array access and the target is a single-dimensional array (§12.8.12.2); -- a string access (§string-access) -- an indexer access and the target type has an indexer with corresponding parameters of either `Index` type (§12.8.12.3) or of a type to which `Index` values are implicitly convertible; or -- an indexer access and the target type conforms to a sequence pattern for which implicit `Index` support is specified (§24.4.2). +- an array access and the target is a single-dimensional array ([§12.8.12.2](expressions.md#128122-array-access)); +- a string access ([§12.8.12.3](expressions.md#128123-string-access)) +- an indexer access and the target type has an indexer with corresponding parameters of either `Index` type ([§12.8.12.4](expressions.md#128124-indexer-access)) or of a type to which `Index` values are implicitly convertible; or +- an indexer access and the target type conforms to a sequence pattern for which implicit `Index` support is specified ([§18.4.2](ranges.md#1842-implicit-index-support)). -## 24.3 The Range type +## 18.3 The Range type The `System.Range` type represents the abstract range of `Index`es from a `Start` index up to, but not including, an `End` index. @@ -170,7 +170,7 @@ The `System.Range` type represents the abstract range of `Index`es from a `Start > *Example* > -> The following examples use the implicit conversion from `int` to `Index` (§24.2) and the `^` (§hat-operator) operator to create the `Index` values for each `Range`: +> The following examples use the implicit conversion from `int` to `Index` ([§18.2](ranges.md#182-the-index-type)) and the `^` ([§12.9.6](expressions.md#1296-hat-operator)) operator to create the `Index` values for each `Range`: > > ```csharp > var firstQuad = new Range(0, 4); // the indices from `0` to `3` @@ -186,7 +186,7 @@ The `System.Range` type represents the abstract range of `Index`es from a `Start > > *end example* -The language-defined operator `..` (§range-operator) creates a `Range` value from `Index` values. +The language-defined operator `..` ([§12.10](expressions.md#1210-range-operator)) creates a `Range` value from `Index` values. > *Example* > @@ -233,7 +233,7 @@ The returned concrete `Range` tuple is a pair of the form `(S, N)` where: - `N` is the number of items in the range, being the difference between the concrete indices for the `End` and `Start` properties; - both values being calculated with respect to `length`. -A concrete range value is *empty* if `N` is zero. An empty concrete range may have an `S` value equal to concrete past-end index (§24.1), a non-empty range may not. When a `Range` which is used to slice (§24.1) a collection is valid and empty with respect to that collection then the resulting slice is an empty collection. +A concrete range value is *empty* if `N` is zero. An empty concrete range may have an `S` value equal to concrete past-end index ([§18.1](ranges.md#181-general)), a non-empty range may not. When a `Range` which is used to slice ([§18.1](ranges.md#181-general)) a collection is valid and empty with respect to that collection then the resulting slice is an empty collection. > *Note:* A consequence of the above is that a `Range` value which is valid and empty with respect to a `length` of zero may be used to slice an empty collection and results in an empty slice. This differs from indexing which throws an exception if the collection is empty. *end note** @@ -254,34 +254,34 @@ A concrete range value is *empty* if `N` is zero. An empty concrete range may ha > var (ix6, len6) = lastTwo.GetOffsetAndLength(6); // ix6 = 4, len6 = 2 > ``` -`Range` implements `IEquatable` and values may be compared for equality based on the abstract value; two `Range` values are equal if and only if the abstract values of the respective `Start` and `End` properties are equal (§24.2). However `Range` values are not ordered and no other comparison operations are provided. +`Range` implements `IEquatable` and values may be compared for equality based on the abstract value; two `Range` values are equal if and only if the abstract values of the respective `Start` and `End` properties are equal ([§18.2](ranges.md#182-the-index-type)). However `Range` values are not ordered and no other comparison operations are provided. > *Note:* `Range` values are unordered both as they are abstract and there is no unique ordering relation. Once converted to a concrete start and length, e.g. by `GetOffsetAndLength`, an ordering relation could be defined. *end note* -`Range` values can be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: +`Range` values can be directly used in the *argument_list* of an *element_access* expression ([§12.8.12](expressions.md#12812-element-access)) which is: -- an array access and the target is a single-dimensional array (§12.8.12.2); -- a string access (§string-access); -- an indexer access and the target type has an indexer with corresponding parameters of either `Range` type (§12.8.12.3) or of a type to which `Range` values are implicitly convertible; or -- an indexer access (§12.8.12.3) and the target type conforms to a sequence pattern for which implicit `Range` support is specified (§24.4.3). +- an array access and the target is a single-dimensional array ([§12.8.12.2](expressions.md#128122-array-access)); +- a string access ([§12.8.12.3](expressions.md#128123-string-access)); +- an indexer access and the target type has an indexer with corresponding parameters of either `Range` type ([§12.8.12.4](expressions.md#128124-indexer-access)) or of a type to which `Range` values are implicitly convertible; or +- an indexer access ([§12.8.12.4](expressions.md#128124-indexer-access)) and the target type conforms to a sequence pattern for which implicit `Range` support is specified ([§18.4.3](ranges.md#1843-implicit-range-support)). -## 24.4 Pattern-based implicit support for Index and Range +## 18.4 Pattern-based implicit support for Index and Range -### 24.4.1 General +### 18.4.1 General -If an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index` or `Range`; fails to be identified as: +If an *element_access* expression ([§12.8.12](expressions.md#12812-element-access)) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index` or `Range`; fails to be identified as: -- an array access (§12.8.12.2), -- a string access (§string-access), or -- an indexer access (§12.8.12.3) as `T` provides no suitable accessible indexer +- an array access ([§12.8.12.2](expressions.md#128122-array-access)), +- a string access ([§12.8.12.3](expressions.md#128123-string-access)), or +- an indexer access ([§12.8.12.4](expressions.md#128124-indexer-access)) as `T` provides no suitable accessible indexer then implicit support for the expression is provided if `T` conforms to a particular pattern. If `T` does not conform to this pattern then a compile-time error occurs. -### 24.4.2 Implicit Index support +### 18.4.2 Implicit Index support -If in any context an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index`; is not valid (§24.4.1) then if in the same context: +If in any context an *element_access* expression ([§12.8.12](expressions.md#12812-element-access)) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index`; is not valid ([§18.4.1](ranges.md#1841-general)) then if in the same context: -- `T` provides accessible members qualifying it as a *sequence* (§24.1); and +- `T` provides accessible members qualifying it as a *sequence* ([§18.1](ranges.md#181-general)); and - the expression `E[0]` is valid and uses the same indexer that qualifies `T` as a sequence then the expression `E[A]` shall be implicitly supported. @@ -293,11 +293,11 @@ Without otherwise constraining implementations of this Standard the order of eva 3. the countable property of `T` is evaluated, if required by the implementation; 4. the get or set accessor of the `int` based indexer of `T` that would be used by `E[0]` in the same context is invoked. -### 24.4.3 Implicit Range support +### 18.4.3 Implicit Range support -If in any context an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid (§24.4.1) then if in the same context: +If in any context an *element_access* expression ([§12.8.12](expressions.md#12812-element-access)) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid ([§18.4.1](ranges.md#1841-general)) then if in the same context: -- `T` provides accessible members qualifying it as both *countable* and *sliceable* (§24.1) +- `T` provides accessible members qualifying it as both *countable* and *sliceable* ([§18.1](ranges.md#181-general)) then the expression `E[A]` shall be implicitly supported. diff --git a/standard/statements.md b/standard/statements.md index f6f98c051..500c60af5 100644 --- a/standard/statements.md +++ b/standard/statements.md @@ -31,7 +31,7 @@ embedded_statement ; ``` -*unsafe_statement* ([§23.2](unsafe-code.md#232-unsafe-contexts)) and *fixed_statement* ([§23.7](unsafe-code.md#237-the-fixed-statement)) are only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_statement* ([§24.2](unsafe-code.md#242-unsafe-contexts)) and *fixed_statement* ([§24.7](unsafe-code.md#247-the-fixed-statement)) are only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). The *embedded_statement* nonterminal is used for statements that appear within other statements. The use of *embedded_statement* rather than *statement* excludes the use of declaration statements and labeled statements in these contexts. @@ -78,7 +78,7 @@ If a statement can possibly be reached by execution, the statement is said to be A warning is reported if a statement other than *throw_statement*, *block*, or *empty_statement* is unreachable. It is specifically not an error for a statement to be unreachable. -> *Note*: To determine whether a particular statement or end point is reachable, a compiler performs flow analysis according to the reachability rules defined for each statement. The flow analysis takes into account the values of constant expressions ([§12.23](expressions.md#1223-constant-expressions)) that control the behavior of statements, but the possible values of non-constant expressions are not considered. In other words, for purposes of control flow analysis, a non-constant expression of a given type is considered to have any possible value of that type. +> *Note*: To determine whether a particular statement or end point is reachable, a compiler performs flow analysis according to the reachability rules defined for each statement. The flow analysis takes into account the values of constant expressions ([§12.24](expressions.md#1224-constant-expressions)) that control the behavior of statements, but the possible values of non-constant expressions are not considered. In other words, for purposes of control flow analysis, a non-constant expression of a given type is considered to have any possible value of that type. > > In the example > @@ -165,7 +165,7 @@ The end point of a block is reachable if the block is empty or if the end point A *block* that contains one or more `yield` statements ([§13.15](statements.md#1315-the-yield-statement)) is called an iterator block. Iterator blocks are used to implement function members as iterators ([§15.15](classes.md#1515-synchronous-and-asynchronous-iterators)). Some additional restrictions apply to iterator blocks: - It is a compile-time error for a `return` statement to appear in an iterator block (but `yield return` statements are permitted). -- It is a compile-time error for an iterator block to contain an unsafe context ([§23.2](unsafe-code.md#232-unsafe-contexts)). An iterator block always defines a safe context, even when its declaration is nested in an unsafe context. +- It is a compile-time error for an iterator block to contain an unsafe context ([§24.2](unsafe-code.md#242-unsafe-contexts)). An iterator block always defines a safe context, even when its declaration is nested in an unsafe context. ### 13.3.2 Statement lists @@ -429,7 +429,7 @@ local_variable_initializer An *explicitly_typed_local_variable_declaration* introduces one or more local variables with the specified *type*. -If a *local_variable_initializer* is present then its type shall be appropriate according to the rules of simple assignment ([§12.21.2](expressions.md#12212-simple-assignment)) or array initialization ([§17.7](arrays.md#177-array-initializers)) and its value is assigned as the initial value of the variable. +If a *local_variable_initializer* is present then its type shall be appropriate according to the rules of simple assignment ([§12.22.2](expressions.md#12222-simple-assignment)) or array initialization ([§17.7](arrays.md#177-array-initializers)) and its value is assigned as the initial value of the variable. #### 13.6.2.4 Explicitly typed ref local variable declarations @@ -447,7 +447,7 @@ ref_local_variable_declarator ; ``` -The initializing *variable_reference* shall have type *type* and meet the same requirements as for a *ref assignment* ([§12.21.3](expressions.md#12213-ref-assignment)). +The initializing *variable_reference* shall have type *type* and meet the same requirements as for a *ref assignment* ([§12.22.3](expressions.md#12223-ref-assignment)). If *ref_kind* is `ref readonly`, the *identifier*s being declared are references to variables that are treated as read-only. Otherwise, if *ref_kind* is `ref`, the *identifier*s being declared are references to variables that shall be writable. @@ -471,7 +471,7 @@ constant_declarator ; ``` -The *type* of a *local_constant_declaration* specifies the type of the constants introduced by the declaration. The type is followed by a list of *constant_declarator*s, each of which introduces a new constant. A *constant_declarator* consists of an *identifier* that names the constant, followed by an “`=`” token, followed by a *constant_expression* ([§12.23](expressions.md#1223-constant-expressions)) that gives the value of the constant. +The *type* of a *local_constant_declaration* specifies the type of the constants introduced by the declaration. The type is followed by a list of *constant_declarator*s, each of which introduces a new constant. A *constant_declarator* consists of an *identifier* that names the constant, followed by an “`=`” token, followed by a *constant_expression* ([§12.24](expressions.md#1224-constant-expressions)) that gives the value of the constant. The *type* and *constant_expression* of a local constant declaration shall follow the same rules as those of a constant member declaration ([§15.4](classes.md#154-constants)). @@ -562,7 +562,7 @@ Unless specified otherwise below, the semantics of all grammar elements is the s The *identifier* of a *local_function_declaration* shall be unique in its declared block scope, including any enclosing local variable declaration spaces. One consequence of this is that overloaded *local_function_declaration*s are not allowed. -A *local_function_declaration* may include one `async` ([§15.14](classes.md#1514-async-functions)) modifier and one `unsafe` ([§23.1](unsafe-code.md#231-general)) modifier. If the declaration includes the `async` modifier then the return type shall be `void` or a `«TaskType»` type ([§15.14.1](classes.md#15141-general)). If the declaration includes the `static` modifier, the function is a ***static local function***; otherwise, it is a ***non-static local function***. It is a compile-time error for *type_parameter_list* or *parameter_list* to contain *attributes*. If the local function is declared in an unsafe context ([§23.2](unsafe-code.md#232-unsafe-contexts)), the local function may include unsafe code, even if the local function declaration doesn’t include the `unsafe` modifier. +A *local_function_declaration* may include one `async` ([§15.14](classes.md#1514-async-functions)) modifier and one `unsafe` ([§24.1](unsafe-code.md#241-general)) modifier. If the declaration includes the `async` modifier then the return type shall be `void` or a `«TaskType»` type ([§15.14.1](classes.md#15141-general)). If the declaration includes the `static` modifier, the function is a ***static local function***; otherwise, it is a ***non-static local function***. It is a compile-time error for *type_parameter_list* or *parameter_list* to contain *attributes*. If the local function is declared in an unsafe context ([§24.2](unsafe-code.md#242-unsafe-contexts)), the local function may include unsafe code, even if the local function declaration doesn’t include the `unsafe` modifier. A local function is declared at block scope. A non-static local function may capture variables from the enclosing scope while a static local function shall not (so it has no access to enclosing locals, parameters, non-static local functions, or `this`). It is a compile-time error if a captured variable is read by the body of a non-static local function but is not definitely assigned before each call to the function. A compiler shall determine which variables are definitely assigned on return ([§9.4.4.33](variables.md#94433-rules-for-variables-in-local-functions)). @@ -570,7 +570,7 @@ When the type of `this` is a struct type, it is a compile-time error for the bod It is a compile-time error for the body of the local function to contain a `goto` statement, a `break` statement, or a `continue` statement whose target is outside the body of the local function. -> *Note*: the above rules for `this` and `goto` mirror the rules for anonymous functions in [§12.19.3](expressions.md#12193-anonymous-function-bodies). *end note* +> *Note*: the above rules for `this` and `goto` mirror the rules for anonymous functions in [§12.20.3](expressions.md#12203-anonymous-function-bodies). *end note* A local function may be called from a lexical point prior to its declaration. However, it is a compile-time error for the function to be declared lexically prior to the declaration of a variable used in the local function ([§7.7](basic-concepts.md#77-scopes)). @@ -695,7 +695,7 @@ An `else` part is associated with the lexically nearest preceding `if` that is a An `if` statement is executed as follows: -- The *boolean_expression* ([§12.24](expressions.md#1224-boolean-expressions)) is evaluated. +- The *boolean_expression* ([§12.25](expressions.md#1225-boolean-expressions)) is evaluated. - If the Boolean expression yields `true`, control is transferred to the first embedded statement. When and if control reaches the end point of that statement, control is transferred to the end point of the `if` statement. - If the Boolean expression yields `false` and if an `else` part is present, control is transferred to the second embedded statement. When and if control reaches the end point of that statement, control is transferred to the end point of the `if` statement. - If the Boolean expression yields `false` and if an `else` part is not present, control is transferred to the end point of the `if` statement. @@ -927,7 +927,7 @@ Multiple labels are permitted in a *switch_section*. -> *Note*: Like the string equality operators ([§12.12.8](expressions.md#12128-string-equality-operators)), the `switch` statement is case sensitive and will execute a given switch section only if the switch expression string exactly matches a `case` label constant. *end note* +> *Note*: Like the string equality operators ([§12.13.8](expressions.md#12138-string-equality-operators)), the `switch` statement is case sensitive and will execute a given switch section only if the switch expression string exactly matches a `case` label constant. *end note* When the governing type of a `switch` statement is `string` or a nullable value type, the value `null` is permitted as a `case` label constant. The *statement_list*s of a *switch_block* may contain declaration statements ([§13.6](statements.md#136-declaration-statements)). The scope of a local variable or constant declared in a switch block is the switch block. @@ -1001,7 +1001,7 @@ while_statement A `while` statement is executed as follows: -- The *boolean_expression* ([§12.24](expressions.md#1224-boolean-expressions)) is evaluated. +- The *boolean_expression* ([§12.25](expressions.md#1225-boolean-expressions)) is evaluated. - If the Boolean expression yields `true`, control is transferred to the embedded statement. When and if control reaches the end point of the embedded statement (possibly from execution of a `continue` statement), control is transferred to the beginning of the `while` statement. - If the Boolean expression yields `false`, control is transferred to the end point of the `while` statement. @@ -1027,7 +1027,7 @@ do_statement A `do` statement is executed as follows: - Control is transferred to the embedded statement. -- When and if control reaches the end point of the embedded statement (possibly from execution of a `continue` statement), the *boolean_expression* ([§12.24](expressions.md#1224-boolean-expressions)) is evaluated. If the Boolean expression yields `true`, control is transferred to the beginning of the `do` statement. Otherwise, control is transferred to the end point of the `do` statement. +- When and if control reaches the end point of the embedded statement (possibly from execution of a `continue` statement), the *boolean_expression* ([§12.25](expressions.md#1225-boolean-expressions)) is evaluated. If the Boolean expression yields `true`, control is transferred to the beginning of the `do` statement. Otherwise, control is transferred to the end point of the `do` statement. Within the embedded statement of a `do` statement, a `break` statement ([§13.10.2](statements.md#13102-the-break-statement)) may be used to transfer control to the end point of the `do` statement (thus ending iteration of the embedded statement), and a `continue` statement ([§13.10.3](statements.md#13103-the-continue-statement)) may be used to transfer control to the end point of the embedded statement (thus performing another iteration of the `do` statement). @@ -1068,7 +1068,7 @@ statement_expression_list The *for_initializer*, if present, consists of either a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)) or a list of *statement_expression*s ([§13.7](statements.md#137-expression-statements)) separated by commas. The scope of a local variable declared by a *for_initializer* is the *for_initializer*, *for_condition*, *for_iterator*, and *embedded_statement*. -The *for_condition*, if present, shall be a *boolean_expression* ([§12.24](expressions.md#1224-boolean-expressions)). +The *for_condition*, if present, shall be a *boolean_expression* ([§12.25](expressions.md#1225-boolean-expressions)). The *for_iterator*, if present, consists of a list of *statement_expression*s ([§13.7](statements.md#137-expression-statements)) separated by commas. @@ -1192,11 +1192,11 @@ is then equivalent to: } ``` -The variable `e` is not visible or accessible to the expression `x` or the embedded statement or any other source code of the program. The reference variable `v` is read-write in the embedded statement, but `v` shall not be ref-reassigned ([§12.21.3](expressions.md#12213-ref-assignment)). If there is not an identity conversion ([§10.2.2](conversions.md#1022-identity-conversion)) from `T` (the iteration type) to `V` (the *local_variable_type* in the `foreach` statement), an error is produced and no further steps are taken. +The variable `e` is not visible or accessible to the expression `x` or the embedded statement or any other source code of the program. The reference variable `v` is read-write in the embedded statement, but `v` shall not be ref-reassigned ([§12.22.3](expressions.md#12223-ref-assignment)). If there is not an identity conversion ([§10.2.2](conversions.md#1022-identity-conversion)) from `T` (the iteration type) to `V` (the *local_variable_type* in the `foreach` statement), an error is produced and no further steps are taken. A `foreach` statement of the form `foreach (ref readonly V v in x) «embedded_statement»` has a similar equivalent form, but the reference variable `v` is `ref readonly` in the embedded statement, and therefore cannot be ref-reassigned or reassigned. -The placement of `v` inside the `while` loop is important for how it is captured ([§12.19.6.2](expressions.md#121962-captured-outer-variables)) by any anonymous function occurring in the *embedded_statement*. +The placement of `v` inside the `while` loop is important for how it is captured ([§12.20.6.2](expressions.md#122062-captured-outer-variables)) by any anonymous function occurring in the *embedded_statement*. > *Example*: > @@ -1326,7 +1326,7 @@ This determination proceeds as follows: - If the return type `E` of the `GetAsyncEnumerator` method is not a class, struct or interface type, an error is produced and no further steps are taken. - Member lookup is performed on `E` with the identifier `Current` and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken. - Member lookup is performed on `E` with the identifier `MoveNextAsync` and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken. - - Overload resolution is performed on the method group with an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not awaitable ([§12.9.8.2](expressions.md#12982-awaitable-expressions)) where the *await_expression* is classified as a `bool` ([§12.9.8.3](expressions.md#12983-classification-of-await-expressions)), an error is produced, and no further steps are taken. + - Overload resolution is performed on the method group with an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not awaitable ([§12.9.9.2](expressions.md#12992-awaitable-expressions)) where the *await_expression* is classified as a `bool` ([§12.9.9.3](expressions.md#12993-classification-of-await-expressions)), an error is produced, and no further steps are taken. - The collection type is `X`, the enumerator type is `E`, and the iteration type is the type of the `Current` property. - Otherwise, check for an asynchronous enumerable interface: - If among all the types `Tᵢ` for which there is an implicit conversion from `X` to `IAsyncEnumerable`, there is a unique type `T` such that `T` is not `dynamic` and for all the other `Tᵢ` there is an implicit conversion from `IAsyncEnumerable` to `IAsyncEnumerable`, then the collection type is the interface `IAsyncEnumerable`, the enumerator type is the interface `IAsyncEnumerator`, and the iteration type is `T`. @@ -1594,7 +1594,7 @@ A function member is said to ***compute a value*** if it is a method with a retu For a return-by-value, an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) shall exist from the type of *expression* to the effective return type ([§15.6.11](classes.md#15611-method-body)) of the containing function member. For a return-by-ref, an identity conversion ([§10.2.2](conversions.md#1022-identity-conversion)) shall exist between the type of *expression* and the effective return type of the containing function member. -`return` statements can also be used in the body of anonymous function expressions ([§12.19](expressions.md#1219-anonymous-function-expressions)), and participate in determining which conversions exist for those functions ([§10.7.1](conversions.md#1071-general)). +`return` statements can also be used in the body of anonymous function expressions ([§12.20](expressions.md#1220-anonymous-function-expressions)), and participate in determining which conversions exist for those functions ([§10.7.1](conversions.md#1071-general)). It is a compile-time error for a `return` statement to appear in a `finally` block ([§13.11](statements.md#1311-the-try-statement)). @@ -1623,7 +1623,7 @@ A `throw` statement with no expression can be used only in a `catch` block, in w Because a `throw` statement unconditionally transfers control elsewhere, the end point of a `throw` statement is never reachable. -When an exception is thrown, control is transferred to the first `catch` clause in an enclosing `try` statement that can handle the exception. The process that takes place from the point of the exception being thrown to the point of transferring control to a suitable exception handler is known as ***exception propagation***. Propagation of an exception consists of repeatedly evaluating the following steps until a `catch` clause that matches the exception is found. In this description, the ***throw point*** is initially the location at which the exception is thrown. This behavior is specified in ([§21.4](exceptions.md#214-how-exceptions-are-handled)). +When an exception is thrown, control is transferred to the first `catch` clause in an enclosing `try` statement that can handle the exception. The process that takes place from the point of the exception being thrown to the point of transferring control to a suitable exception handler is known as ***exception propagation***. Propagation of an exception consists of repeatedly evaluating the following steps until a `catch` clause that matches the exception is found. In this description, the ***throw point*** is initially the location at which the exception is thrown. This behavior is specified in ([§22.4](exceptions.md#224-how-exceptions-are-handled)). - In the current function member, each `try` statement that encloses the throw point is examined. For each statement `S`, starting with the innermost `try` statement and ending with the outermost `try` statement, the following steps are evaluated: diff --git a/standard/structs.md b/standard/structs.md index 2c352ee73..eb353aeb9 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -22,7 +22,7 @@ struct_declaration ; ``` -A *struct_declaration* consists of an optional set of *attributes* ([§22](attributes.md#22-attributes)), followed by an optional set of *struct_modifier*s ([§16.2.2](structs.md#1622-struct-modifiers)), followed by an optional `ref` modifier ([§16.2.3](structs.md#1623-ref-modifier)), followed by an optional partial modifier ([§15.2.7](classes.md#1527-partial-type-declarations)), followed by the keyword `struct` and an *identifier* that names the struct, followed by an optional *type_parameter_list* specification ([§15.2.3](classes.md#1523-type-parameters)), followed by an optional *struct_interfaces* specification ([§16.2.5](structs.md#1625-struct-interfaces)), followed by an optional *type_parameter_constraints-clauses* specification ([§15.2.5](classes.md#1525-type-parameter-constraints)), followed by a *struct_body* ([§16.2.6](structs.md#1626-struct-body)), optionally followed by a semicolon. +A *struct_declaration* consists of an optional set of *attributes* ([§23](attributes.md#23-attributes)), followed by an optional set of *struct_modifier*s ([§16.2.2](structs.md#1622-struct-modifiers)), followed by an optional `ref` modifier ([§16.2.3](structs.md#1623-ref-modifier)), followed by an optional partial modifier ([§15.2.7](classes.md#1527-partial-type-declarations)), followed by the keyword `struct` and an *identifier* that names the struct, followed by an optional *type_parameter_list* specification ([§15.2.3](classes.md#1523-type-parameters)), followed by an optional *struct_interfaces* specification ([§16.2.5](structs.md#1625-struct-interfaces)), followed by an optional *type_parameter_constraints-clauses* specification ([§15.2.5](classes.md#1525-type-parameter-constraints)), followed by a *struct_body* ([§16.2.6](structs.md#1626-struct-body)), optionally followed by a semicolon. A struct declaration shall not supply *type_parameter_constraints_clause*s unless it also supplies a *type_parameter_list*. @@ -46,7 +46,7 @@ struct_modifier ; ``` -*unsafe_modifier* ([§23.2](unsafe-code.md#232-unsafe-contexts)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*unsafe_modifier* ([§24.2](unsafe-code.md#242-unsafe-contexts)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). It is a compile-time error for the same modifier to appear multiple times in a struct declaration. @@ -100,7 +100,7 @@ struct_interfaces The handling of interfaces on multiple parts of a partial struct declaration ([§15.2.7](classes.md#1527-partial-type-declarations)) are discussed further in [§15.2.4.3](classes.md#15243-interface-implementations). -Interface implementations are discussed further in [§18.6](interfaces.md#186-interface-implementations). +Interface implementations are discussed further in [§19.6](interfaces.md#196-interface-implementations). ### 16.2.6 Struct body @@ -132,7 +132,7 @@ struct_member_declaration ; ``` -*fixed_size_buffer_declaration* ([§23.8.2](unsafe-code.md#2382-fixed-size-buffer-declarations)) is only available in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*fixed_size_buffer_declaration* ([§24.8.2](unsafe-code.md#2482-fixed-size-buffer-declarations)) is only available in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). > *Note*: All kinds of *class_member_declaration*s except *finalizer_declaration* are also *struct_member_declaration*s. *end note* @@ -238,7 +238,7 @@ Assignment to a variable of a struct type creates a *copy* of the value being as Similar to an assignment, when a struct is passed as a value parameter or returned as the result of a function member, a copy of the struct is created. A struct may be passed by reference to a function member using a by-reference parameter. -When a property or indexer of a struct is the target of an assignment, the instance expression associated with the property or indexer access shall be classified as a variable. If the instance expression is classified as a value, a compile-time error occurs. This is described in further detail in [§12.21.2](expressions.md#12212-simple-assignment). +When a property or indexer of a struct is the target of an assignment, the instance expression associated with the property or indexer access shall be classified as a variable. If the instance expression is classified as a value, a compile-time error occurs. This is described in further detail in [§12.22.2](expressions.md#12222-simple-assignment). ### 16.4.5 Default values @@ -470,7 +470,7 @@ If the struct instance constructor specifies a constructor initializer, that ini > ``` > > No instance function member (including the set accessors for the properties `X` and `Y`) can be called until all fields of the struct being constructed have been definitely assigned. Note, however, that if `Point` were a class instead of a struct, the instance constructor implementation would be permitted. -> There is one exception to this, and that involves automatically implemented properties ([§15.7.4](classes.md#1574-automatically-implemented-properties)). The definite assignment rules ([§12.21.2](expressions.md#12212-simple-assignment)) specifically exempt assignment to an auto-property of a struct type within an instance constructor of that struct type: such an assignment is considered a definite assignment of the hidden backing field of the auto-property. Thus, the following is allowed: +> There is one exception to this, and that involves automatically implemented properties ([§15.7.4](classes.md#1574-automatically-implemented-properties)). The definite assignment rules ([§12.22.2](expressions.md#12222-simple-assignment)) specifically exempt assignment to an auto-property of a struct type within an instance constructor of that struct type: such an assignment is considered a definite assignment of the hidden backing field of the auto-property. Thus, the following is allowed: > > > ```csharp diff --git a/standard/types.md b/standard/types.md index c1670d09c..f987fdb2a 100644 --- a/standard/types.md +++ b/standard/types.md @@ -13,7 +13,7 @@ type ; ``` -*pointer_type* ([§23.3](unsafe-code.md#233-pointer-types)) is available only in unsafe code ([§23](unsafe-code.md#23-unsafe-code)). +*pointer_type* ([§24.3](unsafe-code.md#243-pointer-types)) is available only in unsafe code ([§24](unsafe-code.md#24-unsafe-code)). Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store ***references*** to their data, the latter being known as ***objects***. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. @@ -85,7 +85,7 @@ nullable_type_annotation ``` -*pointer_type* is available only in unsafe code ([§23.3](unsafe-code.md#233-pointer-types)). *nullable_reference_type* is discussed further in [§8.9](types.md#89-reference-types-and-nullability). +*pointer_type* is available only in unsafe code ([§24.3](unsafe-code.md#243-pointer-types)). *nullable_reference_type* is discussed further in [§8.9](types.md#89-reference-types-and-nullability). A reference type value is a reference to an ***instance*** of the type, the latter known as an object. The special value `null` is compatible with all reference types and indicates the absence of an instance. @@ -102,10 +102,10 @@ Certain predefined class types have special meaning in the C# language, as descr `System.Object` | The ultimate base class of all other types. See [§8.2.3](types.md#823-the-object-type). `System.String` | The string type of the C# language. See [§8.2.5](types.md#825-the-string-type). `System.ValueType` | The base class of all value types. See [§8.3.2](types.md#832-the-systemvaluetype-type). -`System.Enum` | The base class of all `enum` types. See [§19.5](enums.md#195-the-systemenum-type). +`System.Enum` | The base class of all `enum` types. See [§20.5](enums.md#205-the-systemenum-type). `System.Array` | The base class of all array types. See [§17.2.2](arrays.md#1722-the-systemarray-type). -`System.Delegate` | The base class of all `delegate` types. See [§20.1](delegates.md#201-general). -`System.Exception` | The base class of all exception types. See [§21.3](exceptions.md#213-the-systemexception-class). +`System.Delegate` | The base class of all `delegate` types. See [§21.1](delegates.md#211-general). +`System.Exception` | The base class of all exception types. See [§22.3](exceptions.md#223-the-systemexception-class). ### 8.2.3 The object type @@ -131,7 +131,7 @@ The keyword `string` is simply an alias for the predefined class `System.String` An interface defines a contract. A class or struct that implements an interface shall adhere to its contract. An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces. -Interface types are described in [§18](interfaces.md#18-interfaces). +Interface types are described in [§19](interfaces.md#19-interfaces). ### 8.2.7 Array types @@ -145,7 +145,7 @@ A delegate is a data structure that refers to one or more methods. For instance > *Note*: The closest equivalent of a delegate in C or C++ is a function pointer, but whereas a function pointer can only reference static functions, a delegate can reference both static and instance methods. In the latter case, the delegate stores not only a reference to the method’s entry point, but also a reference to the object instance on which to invoke the method. *end note* -Delegate types are described in [§20](delegates.md#20-delegates). +Delegate types are described in [§21](delegates.md#21-delegates). ## 8.3 Value types @@ -307,7 +307,7 @@ Because a simple type aliases a struct type, every simple type has members. > *Note*: The simple types differ from other struct types in that they permit certain additional operations: > > - Most simple types permit values to be created by writing *literals* ([§6.4.5](lexical-structure.md#645-literals)), although C# makes no provision for literals of struct types in general. *Example*: `123` is a literal of type `int` and `'a'` is a literal of type `char`. *end example* -> - When the operands of an expression are all simple type constants, it is possible for a compiler to evaluate the expression at compile-time. Such an expression is known as a *constant_expression* ([§12.23](expressions.md#1223-constant-expressions)). Expressions involving operators defined by other struct types are not considered to be constant expressions +> - When the operands of an expression are all simple type constants, it is possible for a compiler to evaluate the expression at compile-time. Such an expression is known as a *constant_expression* ([§12.24](expressions.md#1224-constant-expressions)). Expressions involving operators defined by other struct types are not considered to be constant expressions > - Through `const` declarations, it is possible to declare constants of the simple types ([§15.4](classes.md#154-constants)). It is not possible to have constants of other struct types, but a similar effect is provided by static readonly fields. > - Conversions involving simple types can participate in evaluation of conversion operators defined by other struct types, but a user-defined conversion operator can never participate in evaluation of another user-defined conversion operator ([§10.5.3](conversions.md#1053-evaluation-of-user-defined-conversions)). > @@ -347,7 +347,7 @@ The `checked` and `unchecked` operators and statements are used to control overf C# supports two floating-point types: `float` and `double`. The `float` and `double` types are represented using the 32-bit single-precision and 64-bit double-precision IEC 60559 formats, which provide the following sets of values: -- Positive zero and negative zero. In most situations, positive zero and negative zero behave identically as the simple value zero, but certain operations distinguish between the two ([§12.10.3](expressions.md#12103-division-operator)). +- Positive zero and negative zero. In most situations, positive zero and negative zero behave identically as the simple value zero, but certain operations distinguish between the two ([§12.11.3](expressions.md#12113-division-operator)). - Positive infinity and negative infinity. Infinities are produced by such operations as dividing a non-zero number by zero. > *Example*: > `1.0 / 0.0` yields positive infinity, and `–1.0 / 0.0` yields negative infinity. @@ -369,7 +369,7 @@ The floating-point operators, including the assignment operators, never produce - If a floating-point operation is invalid, the result of the operation becomes NaN. - If one or both operands of a floating-point operation is NaN, the result of the operation becomes NaN. -Floating-point operations may be performed with higher precision than the result type of the operation. To force a value of a floating-point type to the exact precision of its type, an explicit cast ([§12.9.7](expressions.md#1297-cast-expressions)) can be used. +Floating-point operations may be performed with higher precision than the result type of the operation. To force a value of a floating-point type to the exact precision of its type, an explicit cast ([§12.9.8](expressions.md#1298-cast-expressions)) can be used. > *Example*: Some hardware architectures support an “extended” or “long double” floating-point type with greater range and precision than the `double` type, and implicitly perform all floating-point operations using this higher precision type. Only at excessive cost in performance can such hardware architectures be made to perform floating-point operations with *less* precision, and rather than require an implementation to forfeit both performance and precision, C# allows a higher precision type to be used for all floating-point operations. Other than delivering more precise results, this rarely has any measurable effects. However, in expressions of the form `x * y / z`, where the multiplication produces a result that is outside the `double` range, but the subsequent division brings the temporary result back into the `double` range, the fact that the expression is evaluated in a higher range format can cause a finite result to be produced instead of an infinity. *end example* @@ -399,7 +399,7 @@ No standard conversions exist between `bool` and other value types. In particula ### 8.3.10 Enumeration types -An enumeration type is a distinct type with named constants. Every enumeration type has an underlying type, which shall be `byte`, `sbyte`, `short`, `ushort`, `int`, `uint`, `long` or `ulong`. The set of values of the enumeration type is the same as the set of values of the underlying type. Values of the enumeration type are not restricted to the values of the named constants. Enumeration types are defined through enumeration declarations ([§19.2](enums.md#192-enum-declarations)). +An enumeration type is a distinct type with named constants. Every enumeration type has an underlying type, which shall be `byte`, `sbyte`, `short`, `ushort`, `int`, `uint`, `long` or `ulong`. The set of values of the enumeration type is the same as the set of values of the underlying type. Values of the enumeration type are not restricted to the values of the named constants. Enumeration types are defined through enumeration declarations ([§20.2](enums.md#202-enum-declarations)). ### 8.3.11 Tuple types @@ -468,7 +468,7 @@ creates a non-null instance of `T?` for which the `Value` property is `x`. The p Implicit conversions are available from the `null` literal to `T?` ([§10.2.7](conversions.md#1027-null-literal-conversions)) and from `T` to `T?` ([§10.2.6](conversions.md#1026-implicit-nullable-conversions)). -The nullable value type `T?` implements no interfaces ([§18](interfaces.md#18-interfaces)). In particular, this means it does not implement any interface that the underlying type `T` does. +The nullable value type `T?` implements no interfaces ([§19](interfaces.md#19-interfaces)). In particular, this means it does not implement any interface that the underlying type `T` does. ### 8.3.13 Boxing and unboxing @@ -618,10 +618,10 @@ Since a type parameter can be instantiated with many different type arguments, t > *Note*: These include: > -> - A type parameter cannot be used directly to declare a base class ([§15.2.4.2](classes.md#15242-base-classes)) or interface ([§18.2.4](interfaces.md#1824-base-interfaces)). +> - A type parameter cannot be used directly to declare a base class ([§15.2.4.2](classes.md#15242-base-classes)) or interface ([§19.2.4](interfaces.md#1924-base-interfaces)). > - The rules for member lookup on type parameters depend on the constraints, if any, applied to the type parameter. They are detailed in [§12.5](expressions.md#125-member-lookup). > - The available conversions for a type parameter depend on the constraints, if any, applied to the type parameter. They are detailed in [§10.2.12](conversions.md#10212-implicit-conversions-involving-type-parameters) and [§10.3.8](conversions.md#1038-explicit-conversions-involving-type-parameters). -> - The literal `null` cannot be converted to a type given by a type parameter, except if the type parameter is known to be a reference type ([§10.2.12](conversions.md#10212-implicit-conversions-involving-type-parameters)). However, a default expression ([§12.8.21](expressions.md#12821-default-value-expressions)) can be used instead. In addition, a value with a type given by a type parameter *can* be compared with null using `==` and `!=` ([§12.12.7](expressions.md#12127-reference-type-equality-operators)) unless the type parameter has the value type constraint. +> - The literal `null` cannot be converted to a type given by a type parameter, except if the type parameter is known to be a reference type ([§10.2.12](conversions.md#10212-implicit-conversions-involving-type-parameters)). However, a default expression ([§12.8.21](expressions.md#12821-default-value-expressions)) can be used instead. In addition, a value with a type given by a type parameter *can* be compared with null using `==` and `!=` ([§12.13.7](expressions.md#12137-reference-type-equality-operators)) unless the type parameter has the value type constraint. > - A `new` expression ([§12.8.17.2](expressions.md#128172-object-creation-expressions)) can only be used with a type parameter if the type parameter is constrained by a *constructor_constraint* or the value type constraint ([§15.2.5](classes.md#1525-type-parameter-constraints)). > - A type parameter cannot be used anywhere within an attribute. > - A type parameter cannot be used in a member access ([§12.8.7](expressions.md#1287-member-access)) or type name ([§7.8](basic-concepts.md#78-namespace-and-type-names)) to identify a static member or a nested type. @@ -717,7 +717,7 @@ An *unmanaged_type* is any type that is neither a *reference_type* nor a *type_p - Any *enum_type*. - Any user-defined *struct_type* that contains instance fields of *unmanaged_type*s only. - Any type parameter which is constrained to be unmanaged. -- Any *pointer_type* ([§23.3](unsafe-code.md#233-pointer-types)). +- Any *pointer_type* ([§24.3](unsafe-code.md#243-pointer-types)). ## 8.9 Reference Types and nullability @@ -1096,7 +1096,7 @@ A compiler may issue a warning when nullability annotations differ between two t > > *end example* -A compiler may follow rules for interface variance ([§18.2.3.3](interfaces.md#18233-variance-conversion)), delegate variance ([§20.4](delegates.md#204-delegate-compatibility)), and array covariance ([§17.6](arrays.md#176-array-covariance)) in determining whether to issue a warning for type conversions. +A compiler may follow rules for interface variance ([§19.2.3.3](interfaces.md#19233-variance-conversion)), delegate variance ([§21.4](delegates.md#214-delegate-compatibility)), and array covariance ([§17.6](arrays.md#176-array-covariance)) in determining whether to issue a warning for type conversions. > > ```csharp diff --git a/standard/unsafe-code.md b/standard/unsafe-code.md index 05b570cfc..9d6825717 100644 --- a/standard/unsafe-code.md +++ b/standard/unsafe-code.md @@ -1,6 +1,6 @@ -# 23 Unsafe code +# 24 Unsafe code -## 23.1 General +## 24.1 General An implementation that does not support unsafe code is required to diagnose any usage of the syntactic rules defined in this clause. @@ -16,7 +16,7 @@ An implementation that does not support unsafe code is required to diagnose any > > *end note* -## 23.2 Unsafe contexts +## 24.2 Unsafe contexts The unsafe features of C# are available only in unsafe contexts. An unsafe context is introduced by including an `unsafe` modifier in the declaration of a type, member, or local function, or by employing an *unsafe_statement*: @@ -113,7 +113,7 @@ Other than establishing an unsafe context, thus permitting the use of pointer ty When the `unsafe` modifier is used on a partial type declaration ([§15.2.7](classes.md#1527-partial-type-declarations)), only that particular part is considered an unsafe context. -## 23.3 Pointer types +## 24.3 Pointer types In an unsafe context, a *type* ([§8.1](types.md#81-general)) can be a *pointer_type* as well as a *value_type*, a *reference_type*, or a *type_parameter*. In an unsafe context a *pointer_type* may also be the element type of an array ([§17](arrays.md#17-arrays)). A *pointer_type* may also be used in a typeof expression ([§12.8.18](expressions.md#12818-the-typeof-operator)) outside of an unsafe context (as such usage is not unsafe). @@ -128,7 +128,7 @@ pointer_type The type specified before the `*` in a pointer type is called the ***referent type*** of the pointer type. It represents the type of the variable to which a value of the pointer type points. -A *pointer_type* may only be used in an *array_type* in an unsafe context ([§23.2](unsafe-code.md#232-unsafe-contexts)). A *non_array_type* is any type that is not itself an *array_type*. +A *pointer_type* may only be used in an *array_type* in an unsafe context ([§24.2](unsafe-code.md#242-unsafe-contexts)). A *non_array_type* is any type that is not itself an *array_type*. Unlike references (values of reference types), pointers are not tracked by the garbage collector—the garbage collector has no knowledge of pointers and the data to which they point. For this reason a pointer is not permitted to point to a reference or to a struct that contains references, and the referent type of a pointer shall be an *unmanaged_type*. Pointer types themselves are unmanaged types, so a pointer type may be used as the referent type for another pointer type. @@ -156,15 +156,15 @@ For a given implementation, all pointer types shall have the same size and repre > > *end note* -The value of a pointer having type `T*` represents the address of a variable of type `T`. The pointer indirection operator `*` ([§23.6.2](unsafe-code.md#2362-pointer-indirection)) can be used to access this variable. +The value of a pointer having type `T*` represents the address of a variable of type `T`. The pointer indirection operator `*` ([§24.6.2](unsafe-code.md#2462-pointer-indirection)) can be used to access this variable. > *Example*: Given a variable `P` of type `int*`, the expression `*P` denotes the `int` variable found at the address contained in `P`. *end example* -Like an object reference, a pointer may be `null`. Applying the indirection operator to a `null`-valued pointer results in implementation-defined behavior ([§23.6.2](unsafe-code.md#2362-pointer-indirection)). A pointer with value `null` is represented by all-bits-zero. +Like an object reference, a pointer may be `null`. Applying the indirection operator to a `null`-valued pointer results in implementation-defined behavior ([§24.6.2](unsafe-code.md#2462-pointer-indirection)). A pointer with value `null` is represented by all-bits-zero. -The `void*` type represents a pointer to an unknown type. Because the referent type is unknown, the indirection operator cannot be applied to a pointer of type `void*`, nor can any arithmetic be performed on such a pointer. However, a pointer of type `void*` can be cast to any other pointer type (and vice versa) and compared to values of other pointer types ([§23.6.8](unsafe-code.md#2368-pointer-comparison)). +The `void*` type represents a pointer to an unknown type. Because the referent type is unknown, the indirection operator cannot be applied to a pointer of type `void*`, nor can any arithmetic be performed on such a pointer. However, a pointer of type `void*` can be cast to any other pointer type (and vice versa) and compared to values of other pointer types ([§24.6.8](unsafe-code.md#2468-pointer-comparison)). -Pointer types are a separate category of types. Unlike reference types and value types, pointer types do not inherit from `object` and no conversions exist between pointer types and `object`. In particular, boxing and unboxing ([§8.3.13](types.md#8313-boxing-and-unboxing)) are not supported for pointers. However, conversions are permitted between different pointer types and between pointer types and the integral types. This is described in [§23.5](unsafe-code.md#235-pointer-conversions). +Pointer types are a separate category of types. Unlike reference types and value types, pointer types do not inherit from `object` and no conversions exist between pointer types and `object`. In particular, boxing and unboxing ([§8.3.13](types.md#8313-boxing-and-unboxing)) are not supported for pointers. However, conversions are permitted between different pointer types and between pointer types and the integral types. This is described in [§24.5](unsafe-code.md#245-pointer-conversions). A *pointer_type* cannot be used as a type argument ([§8.4](types.md#84-constructed-types)), and type inference ([§12.6.3](expressions.md#1263-type-inference)) fails on generic method calls that would have inferred a type argument to be a pointer type. @@ -241,37 +241,37 @@ A method can return a value of some type, and that type can be a pointer. In an unsafe context, several constructs are available for operating on pointers: -- The unary `*` operator may be used to perform pointer indirection ([§23.6.2](unsafe-code.md#2362-pointer-indirection)). -- The `->` operator may be used to access a member of a struct through a pointer ([§23.6.3](unsafe-code.md#2363-pointer-member-access)). -- The `[]` operator may be used to index a pointer ([§23.6.4](unsafe-code.md#2364-pointer-element-access)). -- The unary `&` operator may be used to obtain the address of a variable ([§23.6.5](unsafe-code.md#2365-the-address-of-operator)). -- The `++` and `--` operators may be used to increment and decrement pointers ([§23.6.6](unsafe-code.md#2366-pointer-increment-and-decrement)). -- The binary `+` and `-` operators may be used to perform pointer arithmetic ([§23.6.7](unsafe-code.md#2367-pointer-arithmetic)). -- The `==`, `!=`, `<`, `>`, `<=`, and `>=` operators may be used to compare pointers ([§23.6.8](unsafe-code.md#2368-pointer-comparison)). -- The `stackalloc` operator may be used to allocate memory from the call stack ([§23.9](unsafe-code.md#239-stack-allocation)). -- The `fixed` statement may be used to temporarily fix a variable so its address can be obtained ([§23.7](unsafe-code.md#237-the-fixed-statement)). +- The unary `*` operator may be used to perform pointer indirection ([§24.6.2](unsafe-code.md#2462-pointer-indirection)). +- The `->` operator may be used to access a member of a struct through a pointer ([§24.6.3](unsafe-code.md#2463-pointer-member-access)). +- The `[]` operator may be used to index a pointer ([§24.6.4](unsafe-code.md#2464-pointer-element-access)). +- The unary `&` operator may be used to obtain the address of a variable ([§24.6.5](unsafe-code.md#2465-the-address-of-operator)). +- The `++` and `--` operators may be used to increment and decrement pointers ([§24.6.6](unsafe-code.md#2466-pointer-increment-and-decrement)). +- The binary `+` and `-` operators may be used to perform pointer arithmetic ([§24.6.7](unsafe-code.md#2467-pointer-arithmetic)). +- The `==`, `!=`, `<`, `>`, `<=`, and `>=` operators may be used to compare pointers ([§24.6.8](unsafe-code.md#2468-pointer-comparison)). +- The `stackalloc` operator may be used to allocate memory from the call stack ([§24.9](unsafe-code.md#249-stack-allocation)). +- The `fixed` statement may be used to temporarily fix a variable so its address can be obtained ([§24.7](unsafe-code.md#247-the-fixed-statement)). -## 23.4 Fixed and moveable variables +## 24.4 Fixed and moveable variables -The address-of operator ([§23.6.5](unsafe-code.md#2365-the-address-of-operator)) and the `fixed` statement ([§23.7](unsafe-code.md#237-the-fixed-statement)) divide variables into two categories: ***Fixed variables*** and ***moveable variables***. +The address-of operator ([§24.6.5](unsafe-code.md#2465-the-address-of-operator)) and the `fixed` statement ([§24.7](unsafe-code.md#247-the-fixed-statement)) divide variables into two categories: ***Fixed variables*** and ***moveable variables***. Fixed variables reside in storage locations that are unaffected by operation of the garbage collector. (Examples of fixed variables include local variables, value parameters, and variables created by dereferencing pointers.) On the other hand, moveable variables reside in storage locations that are subject to relocation or disposal by the garbage collector. (Examples of moveable variables include fields in objects and elements of arrays.) -The `&` operator ([§23.6.5](unsafe-code.md#2365-the-address-of-operator)) permits the address of a fixed variable to be obtained without restrictions. However, because a moveable variable is subject to relocation or disposal by the garbage collector, the address of a moveable variable can only be obtained using a `fixed statement` ([§23.7](unsafe-code.md#237-the-fixed-statement)), and that address remains valid only for the duration of that `fixed` statement. +The `&` operator ([§24.6.5](unsafe-code.md#2465-the-address-of-operator)) permits the address of a fixed variable to be obtained without restrictions. However, because a moveable variable is subject to relocation or disposal by the garbage collector, the address of a moveable variable can only be obtained using a `fixed statement` ([§24.7](unsafe-code.md#247-the-fixed-statement)), and that address remains valid only for the duration of that `fixed` statement. In precise terms, a fixed variable is one of the following: -- A variable resulting from a *simple_name* ([§12.8.4](expressions.md#1284-simple-names)) that refers to a local variable, value parameter, or parameter array, unless the variable is captured by an anonymous function ([§12.19.6.2](expressions.md#121962-captured-outer-variables)). +- A variable resulting from a *simple_name* ([§12.8.4](expressions.md#1284-simple-names)) that refers to a local variable, value parameter, or parameter array, unless the variable is captured by an anonymous function ([§12.20.6.2](expressions.md#122062-captured-outer-variables)). - A variable resulting from a *member_access* ([§12.8.7](expressions.md#1287-member-access)) of the form `V.I`, where `V` is a fixed variable of a *struct_type*. -- A variable resulting from a *pointer_indirection_expression* ([§23.6.2](unsafe-code.md#2362-pointer-indirection)) of the form `*P`, a *pointer_member_access* ([§23.6.3](unsafe-code.md#2363-pointer-member-access)) of the form `P->I`, or a *pointer_element_access* ([§23.6.4](unsafe-code.md#2364-pointer-element-access)) of the form `P[E]`. +- A variable resulting from a *pointer_indirection_expression* ([§24.6.2](unsafe-code.md#2462-pointer-indirection)) of the form `*P`, a *pointer_member_access* ([§24.6.3](unsafe-code.md#2463-pointer-member-access)) of the form `P->I`, or a *pointer_element_access* ([§24.6.4](unsafe-code.md#2464-pointer-element-access)) of the form `P[E]`. All other variables are classified as moveable variables. A static field is classified as a moveable variable. Also, a by-reference parameter is classified as a moveable variable, even if the argument given for the parameter is a fixed variable. Finally, a variable produced by dereferencing a pointer is always classified as a fixed variable. -## 23.5 Pointer conversions +## 24.5 Pointer conversions -### 23.5.1 General +### 24.5.1 General In an unsafe context, the set of available implicit conversions ([§10.2](conversions.md#102-implicit-conversions)) is extended to include the following implicit pointer conversions: @@ -343,7 +343,7 @@ Mappings between pointers and integers are implementation-defined. > *Note*: However, on 32- and 64-bit CPU architectures with a linear address space, conversions of pointers to or from integral types typically behave exactly like conversions of `uint` or `ulong` values, respectively, to or from those integral types. *end note* -### 23.5.2 Pointer arrays +### 24.5.2 Pointer arrays Arrays of pointers can be constructed using *array_creation_expression* ([§12.8.17.4](expressions.md#128174-array-creation-expressions)) in an unsafe context. Only some of the conversions that apply to other array types are allowed on pointer arrays: @@ -376,13 +376,13 @@ where the type of `x` is an array type of the form `T[,,...,]`, *n* is the numbe } ``` -The variables `a`, `i0`, `i1`, … `in` are not visible to or accessible to `x` or the *embedded_statement* or any other source code of the program. The variable `v` is read-only in the embedded statement. If there is not an explicit conversion ([§23.5](unsafe-code.md#235-pointer-conversions)) from `T` (the element type) to `V`, an error is produced and no further steps are taken. If `x` has the value `null`, a `System.NullReferenceException` is thrown at run-time. +The variables `a`, `i0`, `i1`, … `in` are not visible to or accessible to `x` or the *embedded_statement* or any other source code of the program. The variable `v` is read-only in the embedded statement. If there is not an explicit conversion ([§24.5](unsafe-code.md#245-pointer-conversions)) from `T` (the element type) to `V`, an error is produced and no further steps are taken. If `x` has the value `null`, a `System.NullReferenceException` is thrown at run-time. > *Note*: Although pointer types are not permitted as type arguments, pointer arrays may be used as type arguments. *end note* -## 23.6 Pointers in expressions +## 24.6 Pointers in expressions -### 23.6.1 General +### 24.6.1 General In an unsafe context, an expression may yield a result of a pointer type, but outside an unsafe context, it is a compile-time error for an expression to be of a pointer type. In precise terms, outside an unsafe context a compile-time error occurs if any *simple_name* ([§12.8.4](expressions.md#1284-simple-names)), *member_access* ([§12.8.7](expressions.md#1287-member-access)), *invocation_expression* ([§12.8.10](expressions.md#12810-invocation-expressions)), or *element_access* ([§12.8.12](expressions.md#12812-element-access)) is of a pointer type. @@ -390,7 +390,7 @@ In an unsafe context, the *primary_expression* ([§12.8](expressions.md#128-prim > *Note*: The precedence and associativity of the unsafe operators is implied by the grammar. *end note* -### 23.6.2 Pointer indirection +### 24.6.2 Pointer indirection A *pointer_indirection_expression* consists of an asterisk (`*`) followed by a *unary_expression*. @@ -406,11 +406,11 @@ The effect of applying the unary `*` operator to a `null`-valued pointer is impl If an invalid value has been assigned to the pointer, the behavior of the unary `*` operator is undefined. -> *Note*: Among the invalid values for dereferencing a pointer by the unary `*` operator are an address inappropriately aligned for the type pointed to (see example in [§23.5](unsafe-code.md#235-pointer-conversions)), and the address of a variable after the end of its lifetime. +> *Note*: Among the invalid values for dereferencing a pointer by the unary `*` operator are an address inappropriately aligned for the type pointed to (see example in [§24.5](unsafe-code.md#245-pointer-conversions)), and the address of a variable after the end of its lifetime. For purposes of definite assignment analysis, a variable produced by evaluating an expression of the form `*P` is considered initially assigned ([§9.4.2](variables.md#942-initially-assigned-variables)). -### 23.6.3 Pointer member access +### 24.6.3 Pointer member access A *pointer_member_access* consists of a *primary_expression*, followed by a “`->`” token, followed by an *identifier* and an optional *type_argument_list*. @@ -422,7 +422,7 @@ pointer_member_access In a pointer member access of the form `P->I`, `P` shall be an expression of a pointer type, and `I` shall denote an accessible member of the type to which `P` points. -A pointer member access of the form `P->I` is evaluated exactly as `(*P).I`. For a description of the pointer indirection operator (`*`), see [§23.6.2](unsafe-code.md#2362-pointer-indirection). For a description of the member access operator (`.`), see [§12.8.7](expressions.md#1287-member-access). +A pointer member access of the form `P->I` is evaluated exactly as `(*P).I`. For a description of the pointer indirection operator (`*`), see [§24.6.2](unsafe-code.md#2462-pointer-indirection). For a description of the member access operator (`.`), see [§12.8.7](expressions.md#1287-member-access). > *Example*: In the following code > @@ -474,7 +474,7 @@ A pointer member access of the form `P->I` is evaluated exactly as `(*P).I`. For > > *end example* -### 23.6.4 Pointer element access +### 24.6.4 Pointer element access A *pointer_element_access* consists of a *primary_expression* followed by an expression enclosed in “`[`” and “`]`”. @@ -484,11 +484,11 @@ pointer_element_access ; ``` -When recognising a *primary_expression* if both the *element_access* and *pointer_element_access* ([§23.6.4](unsafe-code.md#2364-pointer-element-access)) alternatives are applicable then the latter shall be chosen if the embedded *primary_expression* is of pointer type ([§23.3](unsafe-code.md#233-pointer-types)). +When recognising a *primary_expression* if both the *element_access* and *pointer_element_access* ([§24.6.4](unsafe-code.md#2464-pointer-element-access)) alternatives are applicable then the latter shall be chosen if the embedded *primary_expression* is of pointer type ([§24.3](unsafe-code.md#243-pointer-types)). In a pointer element access of the form `P[E]`, `P` shall be an expression of a pointer type other than `void*`, and `E` shall be an expression that can be implicitly converted to `int`, `uint`, `long`, or `ulong`. -A pointer element access of the form `P[E]` is evaluated exactly as `*(P + E)`. For a description of the pointer indirection operator (`*`), see [§23.6.2](unsafe-code.md#2362-pointer-indirection). For a description of the pointer addition operator (`+`), see [§23.6.7](unsafe-code.md#2367-pointer-arithmetic). +A pointer element access of the form `P[E]` is evaluated exactly as `*(P + E)`. For a description of the pointer indirection operator (`*`), see [§24.6.2](unsafe-code.md#2462-pointer-indirection). For a description of the pointer addition operator (`+`), see [§24.6.7](unsafe-code.md#2467-pointer-arithmetic). > *Example*: In the following code > @@ -536,7 +536,7 @@ The pointer element access operator does not check for out-of-bounds errors and > *Note*: This is the same as C and C++. *end note* -### 23.6.5 The address-of operator +### 24.6.5 The address-of operator An *addressof_expression* consists of an ampersand (`&`) followed by a *unary_expression*. @@ -546,7 +546,7 @@ addressof_expression ; ``` -Given an expression `E` which is of a type `T` and is classified as a fixed variable ([§23.4](unsafe-code.md#234-fixed-and-moveable-variables)), the construct `&E` computes the address of the variable given by `E`. The type of the result is `T*` and is classified as a value. A compile-time error occurs if `E` is not classified as a variable, if `E` is classified as a read-only local variable, or if `E` denotes a moveable variable. In the last case, a fixed statement ([§23.7](unsafe-code.md#237-the-fixed-statement)) can be used to temporarily “fix” the variable before obtaining its address. +Given an expression `E` which is of a type `T` and is classified as a fixed variable ([§24.4](unsafe-code.md#244-fixed-and-moveable-variables)), the construct `&E` computes the address of the variable given by `E`. The type of the result is `T*` and is classified as a value. A compile-time error occurs if `E` is not classified as a variable, if `E` is classified as a read-only local variable, or if `E` denotes a moveable variable. In the last case, a fixed statement ([§24.7](unsafe-code.md#247-the-fixed-statement)) can be used to temporarily “fix” the variable before obtaining its address. > *Note*: As stated in [§12.8.7](expressions.md#1287-member-access), outside an instance constructor or static constructor for a struct or class that defines a `readonly` field, that field is considered a value, not a variable. As such, its address cannot be taken. Similarly, the address of a constant cannot be taken. *end note* @@ -581,24 +581,24 @@ The `&` operator does not require its argument to be definitely assigned, but fo -> *Note*: When a local variable, value parameter, or parameter array is captured by an anonymous function ([§12.8.24](expressions.md#12824-anonymous-method-expressions)), that local variable, parameter, or parameter array is no longer considered to be a fixed variable ([§23.7](unsafe-code.md#237-the-fixed-statement)), but is instead considered to be a moveable variable. Thus it is an error for any unsafe code to take the address of a local variable, value parameter, or parameter array that has been captured by an anonymous function. *end note* +> *Note*: When a local variable, value parameter, or parameter array is captured by an anonymous function ([§12.8.24](expressions.md#12824-anonymous-method-expressions)), that local variable, parameter, or parameter array is no longer considered to be a fixed variable ([§24.7](unsafe-code.md#247-the-fixed-statement)), but is instead considered to be a moveable variable. Thus it is an error for any unsafe code to take the address of a local variable, value parameter, or parameter array that has been captured by an anonymous function. *end note* -### 23.6.6 Pointer increment and decrement +### 24.6.6 Pointer increment and decrement -In an unsafe context, the `++` and `--` operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators) and [§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators)) can be applied to pointer variables of all types except `void*`. Thus, for every pointer type `T*`, the following operators are implicitly defined: +In an unsafe context, the `++` and `--` operators ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators) and [§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators)) can be applied to pointer variables of all types except `void*`. Thus, for every pointer type `T*`, the following operators are implicitly defined: ```csharp T* operator ++(T* x); T* operator --(T* x); ``` -The operators produce the same results as `x+1` and `x-1`, respectively ([§23.6.7](unsafe-code.md#2367-pointer-arithmetic)). In other words, for a pointer variable of type `T*`, the `++` operator adds `sizeof(T)` to the address contained in the variable, and the `--` operator subtracts `sizeof(T)` from the address contained in the variable. +The operators produce the same results as `x+1` and `x-1`, respectively ([§24.6.7](unsafe-code.md#2467-pointer-arithmetic)). In other words, for a pointer variable of type `T*`, the `++` operator adds `sizeof(T)` to the address contained in the variable, and the `--` operator subtracts `sizeof(T)` from the address contained in the variable. If a pointer increment or decrement operation overflows the domain of the pointer type, the result is implementation-defined, but no exceptions are produced. -### 23.6.7 Pointer arithmetic +### 24.6.7 Pointer arithmetic -In an unsafe context, the `+` operator ([§12.10.5](expressions.md#12105-addition-operator)) and `-` operator ([§12.10.6](expressions.md#12106-subtraction-operator)) can be applied to values of all pointer types except `void*`. Thus, for every pointer type `T*`, the following operators are implicitly defined: +In an unsafe context, the `+` operator ([§12.11.5](expressions.md#12115-addition-operator)) and `-` operator ([§12.11.6](expressions.md#12116-subtraction-operator)) can be applied to values of all pointer types except `void*`. Thus, for every pointer type `T*`, the following operators are implicitly defined: ```csharp T* operator +(T* x, int y); @@ -651,9 +651,9 @@ Given two expressions, `P` and `Q`, of a pointer type `T*`, the expression `P If a pointer arithmetic operation overflows the domain of the pointer type, the result is truncated in an implementation-defined fashion, but no exceptions are produced. -### 23.6.8 Pointer comparison +### 24.6.8 Pointer comparison -In an unsafe context, the `==`, `!=`, `<`, `>`, `<=`, and `>=` operators ([§12.12](expressions.md#1212-relational-and-type-testing-operators)) can be applied to values of all pointer types. The pointer comparison operators are: +In an unsafe context, the `==`, `!=`, `<`, `>`, `<=`, and `>=` operators ([§12.13](expressions.md#1213-relational-and-type-testing-operators)) can be applied to values of all pointer types. The pointer comparison operators are: ```csharp bool operator ==(void* x, void* y); @@ -666,7 +666,7 @@ bool operator >=(void* x, void* y); Because an implicit conversion exists from any pointer type to the `void*` type, operands of any pointer type can be compared using these operators. The comparison operators compare the addresses given by the two operands as if they were unsigned integers. -### 23.6.9 The sizeof operator +### 24.6.9 The sizeof operator For certain predefined types ([§12.8.19](expressions.md#12819-the-sizeof-operator)), the `sizeof` operator yields a constant `int` value. For all other types, the result of the `sizeof` operator is implementation-defined and is classified as a value, not a constant. @@ -676,7 +676,7 @@ For alignment purposes, there may be unnamed padding at the beginning of a struc When applied to an operand that has struct type, the result is the total number of bytes in a variable of that type, including any padding. -## 23.7 The fixed statement +## 24.7 The fixed statement In an unsafe context, the *embedded_statement* ([§13.1](statements.md#131-general)) production permits an additional construct, the fixed statement, which is used to “fix” a moveable variable such that its address remains constant for the duration of the statement. @@ -701,13 +701,13 @@ fixed_pointer_initializer Each *fixed_pointer_declarator* declares a local variable of the given *pointer_type* and initializes that local variable with the address computed by the corresponding *fixed_pointer_initializer*. A local variable declared in a fixed statement is accessible in any *fixed_pointer_initializer*s occurring to the right of that variable’s declaration, and in the *embedded_statement* of the fixed statement. A local variable declared by a fixed statement is considered read-only. A compile-time error occurs if the embedded statement attempts to modify this local variable (via assignment or the `++` and `--` operators) or pass it as a reference or output parameter. -It is an error to use a captured local variable ([§12.19.6.2](expressions.md#121962-captured-outer-variables)), value parameter, or parameter array in a *fixed_pointer_initializer*. A *fixed_pointer_initializer* can be one of the following: +It is an error to use a captured local variable ([§12.20.6.2](expressions.md#122062-captured-outer-variables)), value parameter, or parameter array in a *fixed_pointer_initializer*. A *fixed_pointer_initializer* can be one of the following: -- The token “`&`” followed by a *variable_reference* ([§9.5](variables.md#95-variable-references)) to a moveable variable ([§23.4](unsafe-code.md#234-fixed-and-moveable-variables)) of an unmanaged type `T`, provided the type `T*` is implicitly convertible to the pointer type given in the `fixed` statement. In this case, the initializer computes the address of the given variable, and the variable is guaranteed to remain at a fixed address for the duration of the fixed statement. +- The token “`&`” followed by a *variable_reference* ([§9.5](variables.md#95-variable-references)) to a moveable variable ([§24.4](unsafe-code.md#244-fixed-and-moveable-variables)) of an unmanaged type `T`, provided the type `T*` is implicitly convertible to the pointer type given in the `fixed` statement. In this case, the initializer computes the address of the given variable, and the variable is guaranteed to remain at a fixed address for the duration of the fixed statement. - An expression of an *array_type* with elements of an unmanaged type `T`, provided the type `T*` is implicitly convertible to the pointer type given in the fixed statement. In this case, the initializer computes the address of the first element in the array, and the entire array is guaranteed to remain at a fixed address for the duration of the `fixed` statement. If the array expression is `null` or if the array has zero elements, the initializer computes an address equal to zero. - An expression of type `string`, provided the type `char*` is implicitly convertible to the pointer type given in the `fixed` statement. In this case, the initializer computes the address of the first character in the string, and the entire string is guaranteed to remain at a fixed address for the duration of the `fixed` statement. The behavior of the `fixed` statement is implementation-defined if the string expression is `null`. - An expression of type other than *array_type* or `string`, provided there exists an accessible method or accessible extension method matching the signature `ref [readonly] T GetPinnableReference()`, where `T` is an *unmanaged_type*, and `T*` is implicitly convertible to the pointer type given in the `fixed` statement. In this case, the initializer computes the address of the returned variable, and that variable is guaranteed to remain at a fixed address for the duration of the `fixed` statement. A `GetPinnableReference()` method can be used by the `fixed` statement when overload resolution ([§12.6.4](expressions.md#1264-overload-resolution)) produces exactly one function member and that function member satisfies the preceding conditions. The `GetPinnableReference` method should return a reference to an address equal to zero, such as that returned from `System.Runtime.CompilerServices.Unsafe.NullRef()` when there is no data to pin. -- A *simple_name* or *member_access* that references a fixed-size buffer member of a moveable variable, provided the type of the fixed-size buffer member is implicitly convertible to the pointer type given in the `fixed` statement. In this case, the initializer computes a pointer to the first element of the fixed-size buffer ([§23.8.3](unsafe-code.md#2383-fixed-size-buffers-in-expressions)), and the fixed-size buffer is guaranteed to remain at a fixed address for the duration of the `fixed` statement. +- A *simple_name* or *member_access* that references a fixed-size buffer member of a moveable variable, provided the type of the fixed-size buffer member is implicitly convertible to the pointer type given in the `fixed` statement. In this case, the initializer computes a pointer to the first element of the fixed-size buffer ([§24.8.3](unsafe-code.md#2483-fixed-size-buffers-in-expressions)), and the fixed-size buffer is guaranteed to remain at a fixed address for the duration of the `fixed` statement. For each address computed by a *fixed_pointer_initializer* the `fixed` statement ensures that the variable referenced by the address is not subject to relocation or disposal by the garbage collector for the duration of the `fixed` statement. @@ -904,19 +904,19 @@ Modifying objects of managed type through fixed pointers can result in undefined > *Note*: The automatic null-termination of strings is particularly convenient when calling external APIs that expect “C-style” strings. Note, however, that a string instance is permitted to contain null characters. If such null characters are present, the string will appear truncated when treated as a null-terminated `char*`. *end note* -## 23.8 Fixed-size buffers +## 24.8 Fixed-size buffers -### 23.8.1 General +### 24.8.1 General Fixed-size buffers are used to declare “C-style” in-line arrays as members of structs, and are primarily useful for interfacing with unmanaged APIs. -### 23.8.2 Fixed-size buffer declarations +### 24.8.2 Fixed-size buffer declarations A ***fixed-size buffer*** is a member that represents storage for a fixed-length buffer of variables of a given type. A fixed-size buffer declaration introduces one or more fixed-size buffers of a given element type. > *Note*: Like an array, a fixed-size buffer can be thought of as containing elements. As such, the term *element type* as defined for an array is also used with a fixed-size buffer. *end note* -Fixed-size buffers are only permitted in struct declarations and may only occur in unsafe contexts ([§23.2](unsafe-code.md#232-unsafe-contexts)). +Fixed-size buffers are only permitted in struct declarations and may only occur in unsafe contexts ([§24.2](unsafe-code.md#242-unsafe-contexts)). ```ANTLR fixed_size_buffer_declaration @@ -945,7 +945,7 @@ fixed_size_buffer_declarator ; ``` -A fixed-size buffer declaration may include a set of attributes ([§22](attributes.md#22-attributes)), a `new` modifier ([§15.3.5](classes.md#1535-the-new-modifier)), accessibility modifiers corresponding to any of the declared accessibilities permitted for struct members ([§16.4.3](structs.md#1643-inheritance)) and an `unsafe` modifier ([§23.2](unsafe-code.md#232-unsafe-contexts)). The attributes and modifiers apply to all of the members declared by the fixed-size buffer declaration. It is an error for the same modifier to appear multiple times in a fixed-size buffer declaration. +A fixed-size buffer declaration may include a set of attributes ([§23](attributes.md#23-attributes)), a `new` modifier ([§15.3.5](classes.md#1535-the-new-modifier)), accessibility modifiers corresponding to any of the declared accessibilities permitted for struct members ([§16.4.3](structs.md#1643-inheritance)) and an `unsafe` modifier ([§24.2](unsafe-code.md#242-unsafe-contexts)). The attributes and modifiers apply to all of the members declared by the fixed-size buffer declaration. It is an error for the same modifier to appear multiple times in a fixed-size buffer declaration. A fixed-size buffer declaration is not permitted to include the `static` modifier. @@ -981,7 +981,7 @@ A fixed-size buffer declaration that declares multiple fixed-size buffers is equ > > *end example* -### 23.8.3 Fixed-size buffers in expressions +### 24.8.3 Fixed-size buffers in expressions Member lookup ([§12.5](expressions.md#125-member-lookup)) of a fixed-size buffer member proceeds exactly like member lookup of a field. @@ -993,9 +993,9 @@ In a member access of the form `E.I` where `E.` may be the implicit `this.`, if - If the expression `E.I` does not occur in an unsafe context, a compile-time error occurs. - If `E` is classified as a value, a compile-time error occurs. -- Otherwise, if `E` is a moveable variable ([§23.4](unsafe-code.md#234-fixed-and-moveable-variables)) then: - - If the expression `E.I` is a *fixed_pointer_initializer* ([§23.7](unsafe-code.md#237-the-fixed-statement)), then the result of the expression is a pointer to the first element of the fixed size buffer member `I` in `E`. - - Otherwise if the expression `E.I` is a *primary_expression* ([§12.8.12.1](expressions.md#128121-general)) within an *element_access* ([§12.8.12](expressions.md#12812-element-access)) of the form `E.I[J]`, then the result of `E.I` is a pointer, `P`, to the first element of the fixed size buffer member `I` in `E`, and the enclosing *element_access* is then evaluated as the *pointer_element_access* ([§23.6.4](unsafe-code.md#2364-pointer-element-access)) `P[J]`. +- Otherwise, if `E` is a moveable variable ([§24.4](unsafe-code.md#244-fixed-and-moveable-variables)) then: + - If the expression `E.I` is a *fixed_pointer_initializer* ([§24.7](unsafe-code.md#247-the-fixed-statement)), then the result of the expression is a pointer to the first element of the fixed size buffer member `I` in `E`. + - Otherwise if the expression `E.I` is a *primary_expression* ([§12.8.12.1](expressions.md#128121-general)) within an *element_access* ([§12.8.12](expressions.md#12812-element-access)) of the form `E.I[J]`, then the result of `E.I` is a pointer, `P`, to the first element of the fixed size buffer member `I` in `E`, and the enclosing *element_access* is then evaluated as the *pointer_element_access* ([§24.6.4](unsafe-code.md#2464-pointer-element-access)) `P[J]`. - Otherwise a compile-time error occurs. - Otherwise, `E` references a fixed variable and the result of the expression is a pointer to the first element of the fixed-size buffer member `I` in `E`. The result is of type `S*`, where S is the element type of `I`, and is classified as a value. @@ -1041,17 +1041,17 @@ The subsequent elements of the fixed-size buffer can be accessed using pointer o > > *end example* -### 23.8.4 Definite assignment checking +### 24.8.4 Definite assignment checking Fixed-size buffers are not subject to definite assignment-checking ([§9.4](variables.md#94-definite-assignment)), and fixed-size buffer members are ignored for purposes of definite-assignment checking of struct type variables. When the outermost containing struct variable of a fixed-size buffer member is a static variable, an instance variable of a class instance, or an array element, the elements of the fixed-size buffer are automatically initialized to their default values ([§9.3](variables.md#93-default-values)). In all other cases, the initial content of a fixed-size buffer is undefined. -## 23.9 Stack allocation +## 24.9 Stack allocation See [§12.8.22](expressions.md#12822-stack-allocation) for general information about the operator `stackalloc`. Here, the ability of that operator to result in a pointer is discussed. -When a *stackalloc_expression* occurs as the initializing expression of a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)), where the *local_variable_type* is either a pointer type ([§23.3](unsafe-code.md#233-pointer-types)) or inferred (`var`), the result of the *stackalloc_expression* is a pointer of type `T*`, where `T` is the *unmanaged_type* of the *stackalloc_expression*. In this case the result is a pointer to be beginning of the allocated block. +When a *stackalloc_expression* occurs as the initializing expression of a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)), where the *local_variable_type* is either a pointer type ([§24.3](unsafe-code.md#243-pointer-types)) or inferred (`var`), the result of the *stackalloc_expression* is a pointer of type `T*`, where `T` is the *unmanaged_type* of the *stackalloc_expression*. In this case the result is a pointer to be beginning of the allocated block. > *Example*: > diff --git a/standard/variables.md b/standard/variables.md index 0fe976fed..1bc268e98 100644 --- a/standard/variables.md +++ b/standard/variables.md @@ -71,7 +71,7 @@ For the purpose of definite-assignment checking, an array element is considered ### 9.2.5 Value parameters -A value parameter comes into existence upon invocation of the function member (method, instance constructor, accessor, or operator) or anonymous function to which the parameter belongs, and is initialized with the value of the argument given in the invocation. A value parameter normally ceases to exist when execution of the function body completes. However, if the value parameter is captured by an anonymous function ([§12.19.6.2](expressions.md#121962-captured-outer-variables)), its lifetime extends at least until the delegate or expression tree created from that anonymous function is eligible for garbage collection. +A value parameter comes into existence upon invocation of the function member (method, instance constructor, accessor, or operator) or anonymous function to which the parameter belongs, and is initialized with the value of the argument given in the invocation. A value parameter normally ceases to exist when execution of the function body completes. However, if the value parameter is captured by an anonymous function ([§12.20.6.2](expressions.md#122062-captured-outer-variables)), its lifetime extends at least until the delegate or expression tree created from that anonymous function is eligible for garbage collection. For the purpose of definite-assignment checking, a value parameter is considered initially assigned. @@ -122,9 +122,9 @@ Input parameters are discussed further in [§15.6.2.3.2](classes.md#156232-input A ***local variable*** is declared by a *local_variable_declaration*, *declaration_expression*, *foreach_statement*, or *specific_catch_clause* of a *try_statement*. A local variable can also be declared by certain kinds of *pattern*s ([§11](patterns.md#11-patterns-and-pattern-matching)). For a *foreach_statement*, the local variable is an iteration variable ([§13.9.5](statements.md#1395-the-foreach-statement)). For a *specific_catch_clause*, the local variable is an exception variable ([§13.11](statements.md#1311-the-try-statement)). A local variable declared by a *foreach_statement* or *specific_catch_clause* is considered initially assigned. -A *local_variable_declaration* can occur in a *block*, a *for_statement*, a *switch_block*, or a *using_statement*. A *declaration_expression* can occur as an `out` *argument_value*, and as a *tuple_element* that is the target of a deconstructing assignment ([§12.21.2](expressions.md#12212-simple-assignment)). +A *local_variable_declaration* can occur in a *block*, a *for_statement*, a *switch_block*, or a *using_statement*. A *declaration_expression* can occur as an `out` *argument_value*, and as a *tuple_element* that is the target of a deconstructing assignment ([§12.22.2](expressions.md#12222-simple-assignment)). -The lifetime of a local variable is the portion of program execution during which storage is guaranteed to be reserved for it. This lifetime extends from entry into the scope with which it is associated, at least until execution of that scope ends in some way. (Entering an enclosed *block*, calling a method, or yielding a value from an iterator block suspends, but does not end, execution of the current scope.) If the local variable is captured by an anonymous function ([§12.19.6.2](expressions.md#121962-captured-outer-variables)), its lifetime extends at least until the delegate or expression tree created from the anonymous function, along with any other objects that come to reference the captured variable, are eligible for garbage collection. If the parent scope is entered recursively or iteratively, a new instance of the local variable is created each time, and its initializer, if any, is evaluated each time. +The lifetime of a local variable is the portion of program execution during which storage is guaranteed to be reserved for it. This lifetime extends from entry into the scope with which it is associated, at least until execution of that scope ends in some way. (Entering an enclosed *block*, calling a method, or yielding a value from an iterator block suspends, but does not end, execution of the current scope.) If the local variable is captured by an anonymous function ([§12.20.6.2](expressions.md#122062-captured-outer-variables)), its lifetime extends at least until the delegate or expression tree created from the anonymous function, along with any other objects that come to reference the captured variable, are eligible for garbage collection. If the parent scope is entered recursively or iteratively, a new instance of the local variable is created each time, and its initializer, if any, is evaluated each time. > *Note*: A local variable is instantiated each time its scope is entered. This behavior is visible to user code containing anonymous methods. *end note* @@ -159,7 +159,7 @@ A local variable introduced by a *local_variable_declaration* or *declaration_ex #### 9.2.9.2 Discards -A ***discard*** is a local variable that has no name. A discard is introduced by a declaration expression ([§12.17](expressions.md#1217-declaration-expressions)) with the identifier `_`; and is either implicitly typed (`_` or `var _`) or explicitly typed (`T _`). +A ***discard*** is a local variable that has no name. A discard is introduced by a declaration expression ([§12.18](expressions.md#1218-declaration-expressions)) with the identifier `_`; and is either implicitly typed (`_` or `var _`) or explicitly typed (`T _`). > *Note*: `_` is a valid identifier in many forms of declarations. *end note* @@ -210,7 +210,7 @@ At a given location in the executable code of a function member or an anonymous > > - An initially assigned variable ([§9.4.2](variables.md#942-initially-assigned-variables)) is always considered definitely assigned. > - An initially unassigned variable ([§9.4.3](variables.md#943-initially-unassigned-variables)) is considered definitely assigned at a given location if all possible execution paths leading to that location contain at least one of the following: -> - A simple assignment ([§12.21.2](expressions.md#12212-simple-assignment)) in which the variable is the left operand. +> - A simple assignment ([§12.22.2](expressions.md#12222-simple-assignment)) in which the variable is the left operand. > - An invocation expression ([§12.8.10](expressions.md#12810-invocation-expressions)) or object creation expression ([§12.8.17.2](expressions.md#128172-object-creation-expressions)) that passes the variable as an output parameter. > - For a local variable, a local variable declaration for the variable ([§13.6.2](statements.md#1362-local-variable-declarations)) that includes a variable initializer. > @@ -657,13 +657,13 @@ For all other constant expressions, the definite-assignment state of *v* after t #### 9.4.4.22 General rules for simple expressions -The following rule applies to these kinds of expressions: literals ([§12.8.2](expressions.md#1282-literals)), simple names ([§12.8.4](expressions.md#1284-simple-names)), member access expressions ([§12.8.7](expressions.md#1287-member-access)), non-indexed base access expressions ([§12.8.15](expressions.md#12815-base-access)), `typeof` expressions ([§12.8.18](expressions.md#12818-the-typeof-operator)), default value expressions ([§12.8.21](expressions.md#12821-default-value-expressions)), `nameof` expressions ([§12.8.23](expressions.md#12823-the-nameof-operator)), and declaration expressions ([§12.17](expressions.md#1217-declaration-expressions)). +The following rule applies to these kinds of expressions: literals ([§12.8.2](expressions.md#1282-literals)), simple names ([§12.8.4](expressions.md#1284-simple-names)), member access expressions ([§12.8.7](expressions.md#1287-member-access)), non-indexed base access expressions ([§12.8.15](expressions.md#12815-base-access)), `typeof` expressions ([§12.8.18](expressions.md#12818-the-typeof-operator)), default value expressions ([§12.8.21](expressions.md#12821-default-value-expressions)), `nameof` expressions ([§12.8.23](expressions.md#12823-the-nameof-operator)), and declaration expressions ([§12.18](expressions.md#1218-declaration-expressions)). - The definite-assignment state of *v* at the end of such an expression is the same as the definite-assignment state of *v* at the beginning of the expression. #### 9.4.4.23 General rules for expressions with embedded expressions -The following rules apply to these kinds of expressions: parenthesized expressions ([§12.8.5](expressions.md#1285-parenthesized-expressions)), tuple expressions ([§12.8.6](expressions.md#1286-tuple-expressions)), element access expressions ([§12.8.12](expressions.md#12812-element-access)), base access expressions with indexing ([§12.8.15](expressions.md#12815-base-access)), increment and decrement expressions ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators), [§12.9.6](expressions.md#1296-prefix-increment-and-decrement-operators)), cast expressions ([§12.9.7](expressions.md#1297-cast-expressions)), unary `+`, `-`, `~`, `*` expressions, binary `+`, `-`, `*`, `/`, `%`, `<<`, `>>`, `<`, `<=`, `>`, `>=`, `==`, `!=`, `is`, `as`, `&`, `|`, `^` expressions ([§12.10](expressions.md#1210-arithmetic-operators), [§12.11](expressions.md#1211-shift-operators), [§12.12](expressions.md#1212-relational-and-type-testing-operators), [§12.13](expressions.md#1213-logical-operators)), compound assignment expressions ([§12.21.4](expressions.md#12214-compound-assignment)), `checked` and `unchecked` expressions ([§12.8.20](expressions.md#12820-the-checked-and-unchecked-operators)), array and delegate creation expressions ([§12.8.17](expressions.md#12817-the-new-operator)) , and `await` expressions ([§12.9.8](expressions.md#1298-await-expressions)). +The following rules apply to these kinds of expressions: parenthesized expressions ([§12.8.5](expressions.md#1285-parenthesized-expressions)), tuple expressions ([§12.8.6](expressions.md#1286-tuple-expressions)), element access expressions ([§12.8.12](expressions.md#12812-element-access)), base access expressions with indexing ([§12.8.15](expressions.md#12815-base-access)), increment and decrement expressions ([§12.8.16](expressions.md#12816-postfix-increment-and-decrement-operators), [§12.9.7](expressions.md#1297-prefix-increment-and-decrement-operators)), cast expressions ([§12.9.8](expressions.md#1298-cast-expressions)), unary `+`, `-`, `~`, `*` expressions, binary `+`, `-`, `*`, `/`, `%`, `<<`, `>>`, `<`, `<=`, `>`, `>=`, `==`, `!=`, `is`, `as`, `&`, `|`, `^` expressions ([§12.11](expressions.md#1211-arithmetic-operators), [§12.12](expressions.md#1212-shift-operators), [§12.13](expressions.md#1213-relational-and-type-testing-operators), [§12.14](expressions.md#1214-logical-operators)), compound assignment expressions ([§12.22.4](expressions.md#12224-compound-assignment)), `checked` and `unchecked` expressions ([§12.8.20](expressions.md#12820-the-checked-and-unchecked-operators)), array and delegate creation expressions ([§12.8.17](expressions.md#12817-the-new-operator)) , and `await` expressions ([§12.9.9](expressions.md#1299-await-expressions)). Each of these expressions has one or more subexpressions that are unconditionally evaluated in a fixed order. @@ -677,7 +677,7 @@ For an expression *expr*, which has subexpressions *expr₁*, *expr₂*, …, *e #### 9.4.4.24 Invocation expressions and object creation expressions -If the method to be invoked is a partial method that has no implementing partial method declaration, or is a conditional method for which the call is omitted ([§22.5.3.2](attributes.md#22532-conditional-methods)), then the definite-assignment state of *v* after the invocation is the same as the definite-assignment state of *v* before the invocation. Otherwise the following rules apply: +If the method to be invoked is a partial method that has no implementing partial method declaration, or is a conditional method for which the call is omitted ([§23.5.3.2](attributes.md#23532-conditional-methods)), then the definite-assignment state of *v* after the invocation is the same as the definite-assignment state of *v* before the invocation. Otherwise the following rules apply: For an invocation expression *expr* of the form: @@ -846,7 +846,7 @@ For an expression *expr* of the form: - The definite-assignment state of *v* before *expr_first* is the same as the definite-assignment state of *v* before *expr*. - The definite-assignment state of *v* before *expr_second* is the same as the definite-assignment state of *v* after *expr_first*. - The definite-assignment statement of *v* after *expr* is determined by: - - If *expr_first* is a constant expression ([§12.23](expressions.md#1223-constant-expressions)) with value `null`, then the state of *v* after *expr* is the same as the state of *v* after *expr_second*. + - If *expr_first* is a constant expression ([§12.24](expressions.md#1224-constant-expressions)) with value `null`, then the state of *v* after *expr* is the same as the state of *v* after *expr_second*. - Otherwise, the state of *v* after *expr* is the same as the definite-assignment state of *v* after *expr_first*. #### 9.4.4.30 ?: expressions @@ -861,8 +861,8 @@ For an expression *expr* of the form: - The definite-assignment state of *v* before *expr_true* is definitely assigned if the state of *v* after *expr_cond* is definitely assigned or “definitely assigned after true expression”. - The definite-assignment state of *v* before *expr_false* is definitely assigned if the state of *v* after *expr_cond* is definitely assigned or “definitely assigned after false expression”. - The definite-assignment state of *v* after *expr* is determined by: - - If *expr_cond* is a constant expression ([§12.23](expressions.md#1223-constant-expressions)) with value `true` then the state of *v* after *expr* is the same as the state of *v* after *expr_true*. - - Otherwise, if *expr_cond* is a constant expression ([§12.23](expressions.md#1223-constant-expressions)) with value `false` then the state of *v* after *expr* is the same as the state of *v* after *expr_false*. + - If *expr_cond* is a constant expression ([§12.24](expressions.md#1224-constant-expressions)) with value `true` then the state of *v* after *expr* is the same as the state of *v* after *expr_true*. + - Otherwise, if *expr_cond* is a constant expression ([§12.24](expressions.md#1224-constant-expressions)) with value `false` then the state of *v* after *expr* is the same as the state of *v* after *expr_false*. - Otherwise, if the state of *v* after *expr_true* is definitely assigned and the state of *v* after *expr_false* is definitely assigned, then the state of *v* after *expr* is definitely assigned. - Otherwise, the state of *v* after *expr* is not definitely assigned. @@ -1198,7 +1198,7 @@ For a variable designating a reference to a field, `e.F`: #### 9.7.2.5 Operators -The conditional operator ([§12.18](expressions.md#1218-conditional-operator)), `c ? ref e1 : ref e2`, and reference assignment operator, `= ref e` ([§12.21.1](expressions.md#12211-general)) have reference variables as operands and yield a reference variable. For those operators, the ref-safe-context of the result is the narrowest context among the ref-safe-contexts of all `ref` operands. +The conditional operator ([§12.19](expressions.md#1219-conditional-operator)), `c ? ref e1 : ref e2`, and reference assignment operator, `= ref e` ([§12.22.1](expressions.md#12221-general)) have reference variables as operands and yield a reference variable. For those operators, the ref-safe-context of the result is the narrowest context among the ref-safe-contexts of all `ref` operands. #### 9.7.2.6 Function invocation