diff --git a/standard/classes.md b/standard/classes.md index 594d56fb5..e779b8a83 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -61,6 +61,7 @@ class_modifier | 'abstract' | 'sealed' | 'static' + | 'file' | unsafe_modifier // unsafe code support ; ``` @@ -73,10 +74,22 @@ The `new` modifier is permitted on nested classes. It specifies that the class h The `public`, `protected`, `internal`, and `private` modifiers control the accessibility of the class. Depending on the context in which the class declaration occurs, some of these modifiers might not be permitted ([§7.5.2](basic-concepts.md#752-declared-accessibility)). +It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + 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), that specification shall agree with all other parts that include an accessibility specification. If no part of a partial type includes an accessibility specification, the type is given the appropriate default accessibility ([§7.5.2](basic-concepts.md#752-declared-accessibility)). The `abstract`, `sealed`, and `static` modifiers are discussed in the following subclauses. +The `file` modifier specifies that the type being declared is local to its parent compilation unit. A compilation unit containing a `file`-modified type shall not also contain a type declaration having the same name but without the `file` modifier. + +The `file` modifier shall only appear in a type declaration for a top-level type. + +When a type declaration contains the `file` modifier, that type is said to be a ***file-local type***. + +The implementation shall guarantee that file-local types with the same name declared in different compilation units, are distinct at runtime. The implementation shall guarantee that a file-local type with the same name as a non-file-local type declared in different compilation units, are distinct at runtime. + +A file-local class that is an attribute type may be used an as attribute within both file-local types and non-file-local types, just as if the attribute type were a non-file-local class. + #### 15.2.2.2 Abstract classes The `abstract` modifier is used to indicate that a class is incomplete and that it is intended to be used only as a base class. An ***abstract class*** differs from a ***non-abstract class*** in the following ways: @@ -263,6 +276,8 @@ The direct base class of a class type shall be at least as accessible as the cla 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)). +A file-local class shall not be used as a base type of a non-file-local class. + 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. Given this definition, the complete set of types upon which a class depends is the transitive closure of the *directly depends on* relationship. > *Example*: The following @@ -874,6 +889,8 @@ class_member_declaration ; ``` +The signature of a member in a non-file-local type shall not contain a file-local type. + The members of a class are divided into the following categories: - Constants, which represent constant values associated with the class ([§15.4](classes.md#154-constants)). diff --git a/standard/delegates.md b/standard/delegates.md index 458614ae2..ebeedb3d1 100644 --- a/standard/delegates.md +++ b/standard/delegates.md @@ -29,6 +29,7 @@ delegate_modifier | 'protected' | 'internal' | 'private' + | 'file' | unsafe_modifier // unsafe code support ; ``` @@ -41,7 +42,9 @@ A delegate declaration that supplies a *variant_type_parameter_list* is a generi The `new` modifier is only permitted on delegates declared within another type, in which case it specifies that such a delegate hides an inherited member by the same name, as described in [§15.3.5](classes.md#1535-the-new-modifier). -The `public`, `protected`, `internal`, and `private` modifiers control the accessibility of the delegate type. Depending on the context in which the delegate declaration occurs, some of these modifiers might not be permitted ([§7.5.2](basic-concepts.md#752-declared-accessibility)). +The `public`, `protected`, `internal`, and `private` modifiers control the accessibility of the delegate type. Depending on the context in which the delegate declaration occurs, some of these modifiers might not be permitted ([§7.5.2](basic-concepts.md#752-declared-accessibility)). It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + +The modifier `file` has the same meaning as that for a class declaration ([§15.2.2](classes.md#1522-class-modifiers)). The delegate’s type name is *identifier*. diff --git a/standard/enums.md b/standard/enums.md index 2ed2efe42..18ce32d97 100644 --- a/standard/enums.md +++ b/standard/enums.md @@ -87,11 +87,14 @@ enum_modifier | 'protected' | 'internal' | 'private' + | 'file' ; ``` It is a compile-time error for the same modifier to appear multiple times in an enum declaration. +It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + 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. ## 20.4 Enum members diff --git a/standard/expressions.md b/standard/expressions.md index 82ce81a03..9a92a46ec 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -380,6 +380,8 @@ A member lookup of a name `N` with `K` type arguments in a type `T` is proces - If `T` is a type parameter, then the set is the union of the sets of accessible members named `N` in each of the types specified as a primary constraint or secondary constraint ([§15.2.5](classes.md#1525-type-parameter-constraints)) for `T`, along with the set of accessible members named `N` in `object`. - Otherwise, the set consists of all accessible ([§7.5](basic-concepts.md#75-member-access)) members named `N` in `T`, including inherited members and the accessible members named `N` in `object`. If `T` is a constructed type, the set of members is obtained by substituting type arguments as described in [§15.3.3](classes.md#1533-members-of-constructed-types). Members that include an `override` modifier are excluded from the set. - Next, if `K` is zero, all nested types whose declarations include type parameters are removed. If `K` is not zero, all members with a different number of type parameters are removed. When `K` is zero, methods having type parameters are not removed, since the type inference process ([§12.6.3](expressions.md#1263-type-inference)) might be able to infer the type arguments. +- Next, let *F* be the compilation unit that contains the expression where member lookup is occurring. All members that are file-local types and are not declared in *F* are removed from the set. +- Next, if the set of accessible members contains file-local types, all members that are not file-local types are removed from the set. - Next, if the member is invoked, all non-invocable members are removed from the set. - Next, members that are hidden by other members are removed from the set. For every member `S.M` in the set, where `S` is the type in which the member `M` is declared, the following rules are applied: - If `M` is a constant, field, property, event, or enumeration member, then all members declared in a base type of `S` are removed from the set. diff --git a/standard/interfaces.md b/standard/interfaces.md index 666042de0..2449b5324 100644 --- a/standard/interfaces.md +++ b/standard/interfaces.md @@ -40,6 +40,7 @@ interface_modifier | 'protected' | 'internal' | 'private' + | 'file' | unsafe_modifier // unsafe code support ; ``` @@ -52,6 +53,10 @@ 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. +It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + +The modifier `file` is described in [§15.2.2](classes.md#1522-class-modifiers). + ### 19.2.3 Variant type parameter lists #### 19.2.3.1 General diff --git a/standard/lexical-structure.md b/standard/lexical-structure.md index 1f3a89cba..53f2c64fa 100644 --- a/standard/lexical-structure.md +++ b/standard/lexical-structure.md @@ -604,7 +604,7 @@ keyword | 'byte' | 'case' | 'catch' | 'char' | 'checked' | 'class' | 'const' | 'continue' | 'decimal' | DEFAULT | 'delegate' | 'do' | 'double' | 'else' | 'enum' - | 'event' | 'explicit' | 'extern' | FALSE | 'finally' + | 'event' | 'explicit' | 'extern' | FALSE | 'file' | 'finally' | 'fixed' | 'float' | 'for' | 'foreach' | 'goto' | 'if' | 'implicit' | 'in' | 'int' | 'interface' | 'internal' | 'is' | 'lock' | 'long' | 'namespace' diff --git a/standard/namespaces.md b/standard/namespaces.md index 5650969a7..a4c0b313e 100644 --- a/standard/namespaces.md +++ b/standard/namespaces.md @@ -279,6 +279,8 @@ A *global_using_static_directive* only imports members and types declared direct Ambiguities between multiple *global_using_namespace_directive*s and *global_using_static_directives* are discussed in [§14.4.3](namespaces.md#1443-global-using-namespace-directives). +It is a compile-time error to use a file-local type in a *global_using_static_directive*. + ## 14.5 Using directives ### 14.5.1 General diff --git a/standard/structs.md b/standard/structs.md index ff04afbd9..16d1ade10 100644 --- a/standard/structs.md +++ b/standard/structs.md @@ -69,6 +69,7 @@ struct_modifier | 'internal' | 'private' | 'readonly' + | 'file' | unsafe_modifier // unsafe code support ; ``` @@ -77,6 +78,8 @@ struct_modifier It is a compile-time error for the same modifier to appear multiple times in a struct declaration. +It is a compile-time error for any of the `public`, `protected`, `internal`, and `private` modifiers to be combined with the `file` modifier. + Except for `readonly`, the modifiers of a struct declaration have the same meaning as those of a class declaration ([§15.2.2](classes.md#1522-class-modifiers)). The `readonly` modifier indicates that the *struct_declaration* declares a type whose instances are immutable.