Skip to content

Commit

Permalink
specify nameof expressions
Browse files Browse the repository at this point in the history
Work done to date on nameof expressions
  • Loading branch information
BillWagner committed Oct 26, 2020
1 parent 700ffa0 commit 5a0f68d
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
43 changes: 42 additions & 1 deletion standard/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,7 @@ primary_no_array_creation_expression
| checked_expression
| unchecked_expression
| default_value_expression
| nameof_expression
| anonymous_method_expression
;
```
Expand Down Expand Up @@ -2367,7 +2368,46 @@ If the *type* in a *default_value_expression* evaluates at run-time to a referen

A *default_value_expression* is a constant expression ([§12.20](expressions.md#1220-constant-expressions)) if *type* is a reference type or a type parameter that is known to be a reference type ([§9.2](types.md#92-reference-types)). In addition, a *default_value_expression* is a constant expression if the type is one of the following value types: `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, `double`, `decimal`, `bool,` or any enumeration type.

### 12.7.16 Anonymous method expressions
### §expressions-nameof-expressions Nameof expressions

A *nameof_expression* is used to obtain the name of a program entity as a constant string.

```antlr
nameof_expression
: 'nameof' '(' named_entity ')'
;
named_entity
: simple_name
| named_entity_target '.' identifier type_argument_list?
;
named_entity_target
: 'this'
| 'base'
| named_entity
| predefined_type
| qualified_alias_member
;
```

Grammatically speaking, the *named_entity* operand is always an expression. Because `nameof` is not a keyword, a *nameof_expression* is always syntactically ambiguous with an invocation of the simple name `nameof`. For compatibility reasons, if a name lookup ([§12.7.3](expressions.md#simple-names)) of the name `nameof` succeeds, the expression is treated as an *invocation_expression* -- regardless of whether the invocation is valid. Otherwise it is a *nameof_expression*.

The meaning of the *named_entity* of a *nameof_expression* is the meaning of it as an expression; that is, either as a *simple_name*, a *base_access* or a *member_access*. However, where the lookup described in [§12.7.3](expressions.md#1273-simple-names) and [§12.7.5](expressions.md#1275-member-access) results in an error because an instance member was found in a static context, a *nameof_expression* produces no such error.

It is a compile-time error for a *named_entity* designating a method group to have a *type_argument_list*. It is a compile time error for a *named_entity_target* to have the type `dynamic`.

A *nameof_expression* is a constant expression of type `string`, and has no effect at runtime. Specifically, its *named_entity* is not evaluated, and is ignored for the purposes of definite assignment analysis ([§10.4.4.22](variables.md#104422-general-rules-for-simple-expressions)). Its value is the last identifier of the *named_entity* before the optional final *type_argument_list*, transformed in the following way:

- The prefix "`@`", if used, is removed.
- Each *unicode_escape_sequence* is transformed into its corresponding Unicode character.
- Any *formatting_characters* are removed.

These are the same transformations applied in [§7.4.3](lexical-structure.md#743-identifiers) when testing equality between identifiers.

> TODO: examples
### 12.7.16 Anonymous method expressions

An *anonymous_method_expression* is one of two ways of defining an anonymous function. These are further described in [§12.16](expressions.md#1216-anonymous-function-expressions).

Expand Down Expand Up @@ -5381,6 +5421,7 @@ Only the following constructs are permitted in constant expressions:
- Parenthesized subexpressions, which are themselves constant expressions.
- Cast expressions.
- `checked` and `unchecked` expressions.
- Nameof expressions
- The predefined `+`, `–`, `!`, and `~` unary operators.
- The predefined `+`, `–, `*`, `/`, `%`, `<<`, `>>`, `&`, `|`, `^`, `&&`, `||`, `==`, `!=`, `<`, `>`, `<=`, and `>=` binary operators.
- The `?:` conditional operator.
Expand Down
5 changes: 3 additions & 2 deletions standard/lexical-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,9 @@ contextual_keyword
: 'add' 'alias' 'ascending' 'async' 'await'
| 'by' 'descending' 'dynamic' 'equals' 'from'
| 'get' 'global' 'group' 'into' 'join'
| 'let' 'orderby' 'partial' 'remove' 'select'
| 'set' 'value' 'var' 'where' 'yield'
| 'let' 'nameof' 'orderby' 'partial' 'remove'
| 'select' 'set' 'value' 'var' 'where'
| 'yield'
;
```

Expand Down
2 changes: 1 addition & 1 deletion standard/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ For all other constant expressions, the definite assignment state of *v* after t
#### 10.4.4.22 General rules for simple expressions
The following rule applies to these kinds of expressions: literals ([§12.7.2](expressions.md#1272-literals)), simple names ([§12.7.3](expressions.md#1273-simple-names)), member access expressions ([§12.7.5](expressions.md#1275-member-access)), non-indexed base access expressions ([§12.7.9](expressions.md#1279-base-access)), `typeof` expressions ([§12.7.12](expressions.md#12712-the-typeof-operator)), and default value expressions ([§12.7.15](expressions.md#12715-default-value-expressions)).
The following rule applies to these kinds of expressions: literals ([§12.7.2](expressions.md#1272-literals)), simple names ([§12.7.3](expressions.md#1273-simple-names)), member access expressions ([§12.7.5](expressions.md#1275-member-access)), non-indexed base access expressions ([§12.7.9](expressions.md#1279-base-access)), `typeof` expressions ([§12.7.12](expressions.md#12712-the-typeof-operator)), default value expressions ([§12.7.15](expressions.md#12715-default-value-expressions)), and `nameof` expressionsexpressions-nameof-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.
Expand Down

0 comments on commit 5a0f68d

Please sign in to comment.