diff --git a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md index 85417b7843492..4f99b63cec964 100644 --- a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md +++ b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md @@ -1,5 +1,18 @@ # This document lists known breaking changes in Roslyn after .NET 6 all the way to .NET 7. +## Types cannot be named `file` + +***Introduced in Visual Studio 2022 version 17.4.*** Starting in C# 11, types cannot be named `file`. The compiler will report an error on all such type names. To work around this, the type name and all usages must be escaped with an `@`: + +```csharp +class file {} // Error CS9056 +class @file {} // No error +``` + +This was done as `file` is now a modifier for type declarations. + +You can learn more about this change in the associated [csharplang issue](https://github.com/dotnet/csharplang/issues/6011). + ## Required spaces in #line span directives ***Introduced in .NET SDK 6.0.400, Visual Studio 2022 version 17.3.*** @@ -426,4 +439,4 @@ class @required {} // No error This was done as `required` is now a member modifier for properties and fields. -You can learn more about this change in the associated [csharplang issue](https://github.com/dotnet/csharplang/issues/3630). +You can learn more about this change in the associated [csharplang issue](https://github.com/dotnet/csharplang/issues/3630). \ No newline at end of file diff --git a/docs/contributing/Compiler Test Plan.md b/docs/contributing/Compiler Test Plan.md index f287fc02e3f49..a3d0b6b4f463a 100644 --- a/docs/contributing/Compiler Test Plan.md +++ b/docs/contributing/Compiler Test Plan.md @@ -38,6 +38,7 @@ This document provides guidance for thinking about language interactions and tes # Type and members - Access modifiers (public, protected, internal, protected internal, private protected, private), static, ref - type declarations (class, record class/struct with or without positional members, struct, interface, type parameter) +- file-local types - methods - fields (required and not) - properties (including get/set/init accessors, required and not) diff --git a/eng/config/globalconfigs/Common.globalconfig b/eng/config/globalconfigs/Common.globalconfig index 1766acf873729..b3339efbab8ce 100644 --- a/eng/config/globalconfigs/Common.globalconfig +++ b/eng/config/globalconfigs/Common.globalconfig @@ -41,7 +41,7 @@ dotnet_diagnostic.RS0006.severity = error dotnet_diagnostic.RS0012.severity = warning dotnet_diagnostic.RS0014.severity = warning dotnet_diagnostic.RS0015.severity = warning -dotnet_diagnostic.RS0016.severity = none # PROTOTYPE(ft): re-enable before feature merge +dotnet_diagnostic.RS0016.severity = error dotnet_diagnostic.RS0017.severity = error dotnet_diagnostic.RS0018.severity = warning dotnet_diagnostic.RS0022.severity = error diff --git a/src/CodeStyle/Core/Analyzers/PublicAPI.Unshipped.txt b/src/CodeStyle/Core/Analyzers/PublicAPI.Unshipped.txt index 691883be01a72..4c8f5c4788aaa 100644 --- a/src/CodeStyle/Core/Analyzers/PublicAPI.Unshipped.txt +++ b/src/CodeStyle/Core/Analyzers/PublicAPI.Unshipped.txt @@ -42,6 +42,7 @@ Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.IsPartial.get -> bo Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.IsReadOnly.get -> bool Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.IsRef.get -> bool Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.IsRequired.get -> bool +Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.IsFile.get -> bool Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.IsSealed.get -> bool Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.IsStatic.get -> bool Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.IsUnsafe.get -> bool @@ -58,6 +59,7 @@ Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.WithIsOverride(bool Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.WithIsReadOnly(bool isReadOnly) -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.WithIsRef(bool isRef) -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.WithIsRequired(bool isRequired) -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers +Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.WithIsFile(bool isFile) -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.WithIsSealed(bool isSealed) -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.WithIsStatic(bool isStatic) -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.WithIsUnsafe(bool isUnsafe) -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers @@ -87,6 +89,7 @@ static Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.Partial.get static Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.ReadOnly.get -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers static Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.Ref.get -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers static Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.Required.get -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers +static Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.File.get -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers static Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.Sealed.get -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers static Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.Static.get -> Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers static Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers.TryParse(string value, out Microsoft.CodeAnalysis.Internal.Editing.DeclarationModifiers modifiers) -> bool diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs index 9c977c755319c..ee5c62da9ec38 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs @@ -1819,7 +1819,8 @@ public int Compare(Symbol fst, Symbol snd) if (best.IsFromFile && !secondBest.IsFromFile) { // a lookup of a file type is "better" than a lookup of a non-file type; no need to further diagnose - // PROTOTYPE(ft): some "single symbol" diagnostics are missed here for similar reasons + // https://github.com/dotnet/roslyn/issues/62331 + // some "single symbol" diagnostics are missed here for similar reasons // that make us miss diagnostics when reporting WRN_SameFullNameThisAggAgg. // return first; diff --git a/src/Compilers/CSharp/Portable/Binder/BuckStopsHereBinder.cs b/src/Compilers/CSharp/Portable/Binder/BuckStopsHereBinder.cs index 90d184f2eed49..caa0df8490196 100644 --- a/src/Compilers/CSharp/Portable/Binder/BuckStopsHereBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/BuckStopsHereBinder.cs @@ -26,7 +26,7 @@ internal BuckStopsHereBinder(CSharpCompilation compilation, SyntaxTree? associat /// In speculative scenarios, the syntax tree from the original compilation used as the speculation context. /// This is in some scenarios, such as the binder used for /// or the binder used to bind usings in . - /// PROTOTYPE(ft): what about in EE scenarios? + /// https://github.com/dotnet/roslyn/issues/62332: what about in EE scenarios? /// internal readonly SyntaxTree? AssociatedSyntaxTree; diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 58de8f3365ebf..e07d03a21ee8c 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -7139,6 +7139,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ File type '{0}' cannot be used in a 'global using static' directive. + + Types and aliases cannot be named 'file'. + unsigned right shift diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.UsingsFromOptionsAndDiagnostics.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.UsingsFromOptionsAndDiagnostics.cs index 6068c3d3b99ca..09f02a1f032e3 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.UsingsFromOptionsAndDiagnostics.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.UsingsFromOptionsAndDiagnostics.cs @@ -34,8 +34,6 @@ public static UsingsFromOptionsAndDiagnostics FromOptions(CSharpCompilation comp } var diagnostics = new DiagnosticBag(); - // PROTOTYPE(ft): should usings from compilation options be allowed to bring file types into scope? - // it doesn't seem to work for non-file types within the compilaton, so can probably do the same for file types. var usingsBinder = new InContainerBinder(compilation.GlobalNamespace, new BuckStopsHereBinder(compilation, associatedSyntaxTree: null)); var boundUsings = ArrayBuilder.GetInstance(); var uniqueUsings = PooledHashSet.GetInstance(); diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index b33845e5d07ee..f5c0e9941c3d1 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -2099,12 +2099,12 @@ internal enum ErrorCode ERR_FixedFieldMustNotBeRef = 9049, ERR_RefFieldCannotReferToRefStruct = 9050, - // PROTOTYPE(ft): compress these before feature merge - ERR_FileTypeDisallowedInSignature = 9300, - ERR_FileTypeNoExplicitAccessibility = 9301, - ERR_FileTypeBase = 9302, - ERR_FileTypeNested = 9303, - ERR_GlobalUsingStaticFileType = 9304 + ERR_FileTypeDisallowedInSignature = 9051, + ERR_FileTypeNoExplicitAccessibility = 9052, + ERR_FileTypeBase = 9053, + ERR_FileTypeNested = 9054, + ERR_GlobalUsingStaticFileType = 9055, + ERR_FileTypeNameDisallowed = 9056, #endregion diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index 6e171c1298ea1..0cb52e6c2fea5 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -257,7 +257,7 @@ internal enum MessageID IDS_FeatureRelaxedShiftOperator = MessageBase + 12825, IDS_FeatureRequiredMembers = MessageBase + 12826, IDS_FeatureRefFields = MessageBase + 12827, - IDS_FeatureFileTypes = MessageBase + 12850, // PROTOTYPE(ft): pack ID before merge + IDS_FeatureFileTypes = MessageBase + 12828, } // Message IDs may refer to strings that need to be localized. diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 565b4ba4cbcfc..b16fda396c9e7 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -1251,7 +1251,7 @@ private void ParseModifiers(SyntaxListBuilder tokens, bool forAccessors, bool fo } case DeclarationModifiers.File: - if (!IsFeatureEnabled(MessageID.IDS_FeatureFileTypes) && !ShouldContextualKeywordBeTreatedAsModifier(parsingStatementNotDeclaration: false)) + if ((!IsFeatureEnabled(MessageID.IDS_FeatureFileTypes) || forTopLevelStatements) && !ShouldContextualKeywordBeTreatedAsModifier(parsingStatementNotDeclaration: false)) { return; } diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt index 623654949ba86..bfbee81018f48 100644 --- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt @@ -5,6 +5,7 @@ Microsoft.CodeAnalysis.CSharp.SyntaxKind.InterpolatedSingleLineRawStringStartTok Microsoft.CodeAnalysis.CSharp.SyntaxKind.MultiLineRawStringLiteralToken = 8519 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.RequiredKeyword = 8447 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.ScopedKeyword = 8448 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.FileKeyword = 8449 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.SingleLineRawStringLiteralToken = 8518 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConstructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax! parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorInitializerSyntax? initializer, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax! body) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax! *REMOVED*static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConstructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax! parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorInitializerSyntax! initializer, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax! body) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax! diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 2accc178cd4f6..eb9c4c3be96b4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -274,7 +274,8 @@ private DeclarationModifiers MakeModifiers(TypeKind typeKind, BindingDiagnosticB { Symbol containingSymbol = this.ContainingSymbol; DeclarationModifiers defaultAccess; - // PROTOTYPE(ft): confirm whether 'file' types can be nested + + // note: we give a specific diagnostic when a file type is nested var allowedModifiers = DeclarationModifiers.AccessibilityMask | DeclarationModifiers.File; if (containingSymbol.Kind == SymbolKind.Namespace) @@ -476,7 +477,8 @@ internal static void ReportReservedTypeName(string? name, CSharpCompilation comp } if (reportIfContextual(SyntaxKind.RecordKeyword, MessageID.IDS_FeatureRecords, ErrorCode.WRN_RecordNamedDisallowed) - || reportIfContextual(SyntaxKind.RequiredKeyword, MessageID.IDS_FeatureRequiredMembers, ErrorCode.ERR_RequiredNameDisallowed)) + || reportIfContextual(SyntaxKind.RequiredKeyword, MessageID.IDS_FeatureRequiredMembers, ErrorCode.ERR_RequiredNameDisallowed) + || reportIfContextual(SyntaxKind.FileKeyword, MessageID.IDS_FeatureFileTypes, ErrorCode.ERR_FileTypeNameDisallowed)) { return; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs index 0a020a570ea52..781b6bac6a5c7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs @@ -453,7 +453,6 @@ private TypeWithAnnotations ComputeType(Binder binder, SyntaxNode syntax, Bindin if (type.Type.IsFileTypeOrUsesFileTypes() && !ContainingType.IsFileTypeOrUsesFileTypes()) { - // PROTOTYPE(ft): should explicit interface implementations be allowed to use file types in signatures? diagnostics.Add(ErrorCode.ERR_FileTypeDisallowedInSignature, Location, type.Type, ContainingType); } diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 1b1deec2d407e..5e39ad0819175 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 11750c3594d54..d85bca7010f4c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 1b2696dcd9286..5bda9f5c4481f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 934be541f7460..6d8f3c6681898 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index aa5b8ade54759..ca711e6b4ba31 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 437eefdfec647..5b05461c673de 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 54cc83d5cc26f..dfa5c51e9556a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 09b88470e3dba..0c0d0fefb9c9b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 29ee38c96cd19..9bd8242b1e766 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index cac0d81fe7c77..7d0ac87fca09c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index a0208ccb1d4cc..3083e5bfd941f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 0f9e9fae47e7c..30de34a5fe134 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 720c77fec0f2d..4d565648e74a0 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -592,6 +592,11 @@ File type '{0}' cannot be used in a member signature in non-file type '{1}'. + + Types and aliases cannot be named 'file'. + Types and aliases cannot be named 'file'. + + File type '{0}' must be defined in a top level type; '{0}' is a nested type. File type '{0}' must be defined in a top level type; '{0}' is a nested type. diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/FileModifierTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/FileModifierTests.cs index be9266768eb8a..1316c04be7c7b 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/FileModifierTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/FileModifierTests.cs @@ -46,13 +46,13 @@ class Outer // (3,16): error CS8652: The feature 'file types' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // file class C { } Diagnostic(ErrorCode.ERR_FeatureInPreview, "C").WithArguments("file types").WithLocation(3, 16), - // (3,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (3,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C { } Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16)); comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (3,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (3,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C { } Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16)); } @@ -108,13 +108,13 @@ public void Nested_03() // (3,16): error CS8652: The feature 'file types' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // file class C { } Diagnostic(ErrorCode.ERR_FeatureInPreview, "C").WithArguments("file types").WithLocation(3, 16), - // (3,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (3,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C { } Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16)); comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (3,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (3,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C { } Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16)); } @@ -136,7 +136,7 @@ class D var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (8,10): error CS9300: File type 'Outer.C' cannot be used in a member signature in non-file type 'D'. + // (8,10): error CS9051: File type 'Outer.C' cannot be used in a member signature in non-file type 'D'. // void M(Outer.C c) { } // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M").WithArguments("Outer.C", "D").WithLocation(8, 10)); } @@ -395,7 +395,7 @@ static void Main() var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (10,12): error CS9300: File type 'E' cannot be used in a member signature in non-file type 'Attr'. + // (10,12): error CS9051: File type 'E' cannot be used in a member signature in non-file type 'Attr'. // public Attr(E e) { } // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "Attr").WithArguments("E", "Attr").WithLocation(10, 12)); } @@ -1069,7 +1069,7 @@ public static void M() """; var comp = CreateCompilation(new[] { source1, source2 }); - // PROTOTYPE(ft): should this diagnostic be more specific? + // https://github.com/dotnet/roslyn/issues/62333: should this diagnostic be more specific? // the issue more precisely is that a definition for 'C' already exists in the current file--not that it's already in this namespace. comp.VerifyDiagnostics( // (8,12): error CS0101: The namespace '' already contains a definition for 'C' @@ -1101,7 +1101,6 @@ public static void M() Diagnostic(ErrorCode.ERR_MissingPartial, "C").WithArguments("C").WithLocation(8, 12)); var c = comp.GetMember("C"); - // PROTOTYPE(ft): is it a problem that we consider this symbol a file type in this scenario? Assert.True(c is SourceMemberContainerTypeSymbol { IsFile: true }); syntaxReferences = c.DeclaringSyntaxReferences; Assert.Equal(3, syntaxReferences.Length); @@ -1219,10 +1218,10 @@ public class C var compilation = CreateCompilation(new[] { source1, source2, source3 }); compilation.VerifyDiagnostics( - // (3,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (3,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16), - // (3,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (3,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16)); @@ -1442,10 +1441,10 @@ class D var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (7,17): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (7,17): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // public void M1(C c) { } // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M1").WithArguments("C", "D").WithLocation(7, 17), - // (8,18): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (8,18): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // private void M2(C c) { } // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M2").WithArguments("C", "D").WithLocation(8, 18)); } @@ -1467,10 +1466,10 @@ class D var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (7,14): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (7,14): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // public C M1() => new C(); // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M1").WithArguments("C", "D").WithLocation(7, 14), - // (8,15): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (8,15): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // private C M2() => new C(); // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M2").WithArguments("C", "D").WithLocation(8, 15)); } @@ -1495,19 +1494,19 @@ public class E var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (8,7): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'E'. + // (8,7): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'E'. // C field; // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "field").WithArguments("C", "E").WithLocation(8, 7), // (8,7): warning CS0169: The field 'E.field' is never used // C field; // 1 Diagnostic(ErrorCode.WRN_UnreferencedField, "field").WithArguments("E.field").WithLocation(8, 7), - // (9,7): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'E'. + // (9,7): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'E'. // C property { get; set; } // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "property").WithArguments("C", "E").WithLocation(9, 7), - // (10,12): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'E'. + // (10,12): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'E'. // object this[C c] { get => c; set { } } // 3 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "this").WithArguments("C", "E").WithLocation(10, 12), - // (11,13): error CS9300: File type 'D' cannot be used in a member signature in non-file type 'E'. + // (11,13): error CS9051: File type 'D' cannot be used in a member signature in non-file type 'E'. // event D @event; // 4 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "@event").WithArguments("D", "E").WithLocation(11, 13), // (11,13): warning CS0067: The event 'E.event' is never used @@ -1536,19 +1535,19 @@ public class E var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (9,13): error CS9300: File type 'C.Inner' cannot be used in a member signature in non-file type 'E'. + // (9,13): error CS9051: File type 'C.Inner' cannot be used in a member signature in non-file type 'E'. // C.Inner field; // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "field").WithArguments("C.Inner", "E").WithLocation(9, 13), // (9,13): warning CS0169: The field 'E.field' is never used // C.Inner field; // 1 Diagnostic(ErrorCode.WRN_UnreferencedField, "field").WithArguments("E.field").WithLocation(9, 13), - // (10,13): error CS9300: File type 'C.Inner' cannot be used in a member signature in non-file type 'E'. + // (10,13): error CS9051: File type 'C.Inner' cannot be used in a member signature in non-file type 'E'. // C.Inner property { get; set; } // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "property").WithArguments("C.Inner", "E").WithLocation(10, 13), - // (11,12): error CS9300: File type 'C.Inner' cannot be used in a member signature in non-file type 'E'. + // (11,12): error CS9051: File type 'C.Inner' cannot be used in a member signature in non-file type 'E'. // object this[C.Inner inner] { get => inner; set { } } // 3 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "this").WithArguments("C.Inner", "E").WithLocation(11, 12), - // (12,27): error CS9300: File type 'C.InnerDelegate' cannot be used in a member signature in non-file type 'E'. + // (12,27): error CS9051: File type 'C.InnerDelegate' cannot be used in a member signature in non-file type 'E'. // event C.InnerDelegate @event; // 4 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "@event").WithArguments("C.InnerDelegate", "E").WithLocation(12, 27), // (12,27): warning CS0067: The event 'E.event' is never used @@ -1593,16 +1592,16 @@ public class Inner var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (24,17): error CS9300: File type 'C.Inner' cannot be used in a member signature in non-file type 'E.Inner'. + // (24,17): error CS9051: File type 'C.Inner' cannot be used in a member signature in non-file type 'E.Inner'. // C.Inner field; // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "field").WithArguments("C.Inner", "E.Inner").WithLocation(24, 17), - // (25,17): error CS9300: File type 'C.Inner' cannot be used in a member signature in non-file type 'E.Inner'. + // (25,17): error CS9051: File type 'C.Inner' cannot be used in a member signature in non-file type 'E.Inner'. // C.Inner property { get; set; } // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "property").WithArguments("C.Inner", "E.Inner").WithLocation(25, 17), - // (26,16): error CS9300: File type 'C.Inner' cannot be used in a member signature in non-file type 'E.Inner'. + // (26,16): error CS9051: File type 'C.Inner' cannot be used in a member signature in non-file type 'E.Inner'. // object this[C.Inner inner] { get => inner; set { } } // 3 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "this").WithArguments("C.Inner", "E.Inner").WithLocation(26, 16), - // (27,31): error CS9300: File type 'C.InnerDelegate' cannot be used in a member signature in non-file type 'E.Inner'. + // (27,31): error CS9051: File type 'C.InnerDelegate' cannot be used in a member signature in non-file type 'E.Inner'. // event C.InnerDelegate @event; // 4 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "@event").WithArguments("C.InnerDelegate", "E.Inner").WithLocation(27, 31)); } @@ -1621,10 +1620,10 @@ public void SignatureUsage_06() var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (5,15): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'Del1'. + // (5,15): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'Del1'. // delegate void Del1(C c); // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "Del1").WithArguments("C", "Del1").WithLocation(5, 15), - // (6,12): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'Del2'. + // (6,12): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'Del2'. // delegate C Del2(); // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "Del2").WithArguments("C", "Del2").WithLocation(6, 12)); } @@ -1646,10 +1645,10 @@ class D var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (7,30): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (7,30): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // public static D operator +(D d, C c) => d; // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "+").WithArguments("C", "D").WithLocation(7, 30), - // (8,30): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (8,30): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // public static C operator -(D d1, D d2) => new C(); // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "-").WithArguments("C", "D").WithLocation(8, 30)); } @@ -1670,7 +1669,7 @@ class D var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (7,12): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (7,12): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // public D(C c) { } // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "D").WithArguments("C", "D").WithLocation(7, 12)); } @@ -1691,13 +1690,13 @@ class D var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (7,14): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (7,14): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // public C M(C c1, C c2) => c1; // 1, 2, 3 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M").WithArguments("C", "D").WithLocation(7, 14), - // (7,14): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (7,14): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // public C M(C c1, C c2) => c1; // 1, 2, 3 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M").WithArguments("C", "D").WithLocation(7, 14), - // (7,14): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'D'. + // (7,14): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'D'. // public C M(C c1, C c2) => c1; // 1, 2, 3 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M").WithArguments("C", "D").WithLocation(7, 14)); } @@ -1714,13 +1713,13 @@ public void AccessModifiers_01() var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (1,19): error CS9301: File type 'C' cannot use accessibility modifiers. + // (1,19): error CS9052: File type 'C' cannot use accessibility modifiers. // public file class C { } // 1 Diagnostic(ErrorCode.ERR_FileTypeNoExplicitAccessibility, "C").WithArguments("C").WithLocation(1, 19), - // (2,21): error CS9301: File type 'D' cannot use accessibility modifiers. + // (2,21): error CS9052: File type 'D' cannot use accessibility modifiers. // file internal class D { } // 2 Diagnostic(ErrorCode.ERR_FileTypeNoExplicitAccessibility, "D").WithArguments("D").WithLocation(2, 21), - // (3,20): error CS9301: File type 'E' cannot use accessibility modifiers. + // (3,20): error CS9052: File type 'E' cannot use accessibility modifiers. // private file class E { } // 3, 4 Diagnostic(ErrorCode.ERR_FileTypeNoExplicitAccessibility, "E").WithArguments("E").WithLocation(3, 20), // (3,20): error CS1527: Elements defined in a namespace cannot be explicitly declared as private, protected, protected internal, or private protected @@ -1758,13 +1757,13 @@ public class Derived2 : Base { } // 2, 3 var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (2,7): error CS9301: File type 'Base' cannot be used as a base type of non-file type 'Derived1'. + // (2,7): error CS9053: File type 'Base' cannot be used as a base type of non-file type 'Derived1'. // class Derived1 : Base { } // 1 Diagnostic(ErrorCode.ERR_FileTypeBase, "Derived1").WithArguments("Base", "Derived1").WithLocation(2, 7), // (3,14): error CS0060: Inconsistent accessibility: base class 'Base' is less accessible than class 'Derived2' // public class Derived2 : Base { } // 2, 3 Diagnostic(ErrorCode.ERR_BadVisBaseClass, "Derived2").WithArguments("Derived2", "Base").WithLocation(3, 14), - // (3,14): error CS9301: File type 'Base' cannot be used as a base type of non-file type 'Derived2'. + // (3,14): error CS9053: File type 'Base' cannot be used as a base type of non-file type 'Derived2'. // public class Derived2 : Base { } // 2, 3 Diagnostic(ErrorCode.ERR_FileTypeBase, "Derived2").WithArguments("Base", "Derived2").WithLocation(3, 14)); } @@ -1784,7 +1783,7 @@ interface Derived3 : Interface { } // 1 var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (6,11): error CS9301: File type 'Interface' cannot be used as a base type of non-file type 'Derived3'. + // (6,11): error CS9053: File type 'Interface' cannot be used as a base type of non-file type 'Derived3'. // interface Derived3 : Interface { } // 1 Diagnostic(ErrorCode.ERR_FileTypeBase, "Derived3").WithArguments("Interface", "Derived3").WithLocation(6, 11)); } @@ -1889,7 +1888,7 @@ partial interface Derived : I2 { } var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (3,19): error CS9302: File type 'I1' cannot be used as a base type of non-file type 'Derived'. + // (3,19): error CS9053: File type 'I1' cannot be used as a base type of non-file type 'Derived'. // partial interface Derived : I1 { } // 1 Diagnostic(ErrorCode.ERR_FileTypeBase, "Derived").WithArguments("I1", "Derived").WithLocation(3, 19)); } @@ -1928,7 +1927,7 @@ class C : I var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (7,17): error CS9300: File type 'I' cannot be used in a member signature in non-file type 'C'. + // (7,17): error CS9051: File type 'I' cannot be used in a member signature in non-file type 'C'. // public void F(I i) { } // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "F").WithArguments("I", "C").WithLocation(7, 17)); } @@ -1943,14 +1942,14 @@ public void InterfaceImplementation_03() } class C : I { - void I.F(I i) { } // PROTOTYPE(ft): is this acceptable, since it's only callable by casting to the referenced file type? + void I.F(I i) { } } """; var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (7,12): error CS9300: File type 'I' cannot be used in a member signature in non-file type 'C'. - // void I.F(I i) { } // PROTOTYPE(ft): is this acceptable, since it's only callable by casting to the referenced file type? + // (7,12): error CS9051: File type 'I' cannot be used in a member signature in non-file type 'C'. + // void I.F(I i) { } Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "F").WithArguments("I", "C").WithLocation(7, 12)); } @@ -2034,19 +2033,19 @@ unsafe class Program // (1,28): warning CS0649: Field 'S.X' is never assigned to, and will always have its default value 0 // file struct S { public int X; } Diagnostic(ErrorCode.WRN_UnassignedInternalField, "X").WithArguments("S.X", "0").WithLocation(1, 28), - // (5,18): error CS9300: File type 'Container' cannot be used in a member signature in non-file type 'Program'. + // (5,18): error CS9051: File type 'Container' cannot be used in a member signature in non-file type 'Program'. // Container M1() => new Container(); // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M1").WithArguments("Container", "Program").WithLocation(5, 18), - // (6,9): error CS9300: File type 'S[]' cannot be used in a member signature in non-file type 'Program'. + // (6,9): error CS9051: File type 'S[]' cannot be used in a member signature in non-file type 'Program'. // S[] M2() => new S[0]; // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M2").WithArguments("S[]", "Program").WithLocation(6, 9), - // (7,12): error CS9300: File type '(S, S)' cannot be used in a member signature in non-file type 'Program'. + // (7,12): error CS9051: File type '(S, S)' cannot be used in a member signature in non-file type 'Program'. // (S, S) M3() => (new S(), new S()); // 3 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M3").WithArguments("(S, S)", "Program").WithLocation(7, 12), - // (8,8): error CS9300: File type 'S*' cannot be used in a member signature in non-file type 'Program'. + // (8,8): error CS9051: File type 'S*' cannot be used in a member signature in non-file type 'Program'. // S* M4() => null; // 4 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M4").WithArguments("S*", "Program").WithLocation(8, 8), - // (9,24): error CS9300: File type 'delegate*' cannot be used in a member signature in non-file type 'Program'. + // (9,24): error CS9051: File type 'delegate*' cannot be used in a member signature in non-file type 'Program'. // delegate* M5() => null; // 5 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M5").WithArguments("delegate*", "Program").WithLocation(9, 24)); } @@ -2070,7 +2069,7 @@ class E var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (10,30): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'E.M(T)'. + // (10,30): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'E.M(T)'. // void M(T t) where T : C { } // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "C").WithArguments("C", "E.M(T)").WithLocation(10, 30)); } @@ -2090,16 +2089,16 @@ record struct R2(C c); // 2 var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }); comp.VerifyDiagnostics( - // (3,8): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'R1'. + // (3,8): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'R1'. // record R1(C c); // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "R1").WithArguments("C", "R1").WithLocation(3, 8), - // (3,8): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'R1'. + // (3,8): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'R1'. // record R1(C c); // 1 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "R1").WithArguments("C", "R1").WithLocation(3, 8), - // (4,15): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'R2'. + // (4,15): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'R2'. // record struct R2(C c); // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "R2").WithArguments("C", "R2").WithLocation(4, 15), - // (4,15): error CS9300: File type 'C' cannot be used in a member signature in non-file type 'R2'. + // (4,15): error CS9051: File type 'C' cannot be used in a member signature in non-file type 'R2'. // record struct R2(C c); // 2 Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "R2").WithArguments("C", "R2").WithLocation(4, 15) ); @@ -2231,7 +2230,7 @@ public static void Main() var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (5,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (5,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C // 1 Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(5, 16), // (15,15): error CS0122: 'Outer.C' is inaccessible due to its protection level @@ -2272,7 +2271,7 @@ static void Main() // (5,15): error CS0117: 'Outer' does not contain a definition for 'C' // Outer.C.M(); // 1 Diagnostic(ErrorCode.ERR_NoSuchMember, "C").WithArguments("Outer", "C").WithLocation(5, 15), - // (5,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (5,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(5, 16)); } @@ -2369,7 +2368,7 @@ public static void Main() // (1,1): hidden CS8019: Unnecessary using directive. // global using static C; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "global using static C;").WithLocation(1, 1), - // (1,21): error CS9304: File type 'C' cannot be used in a 'global using static' directive. + // (1,21): error CS9055: File type 'C' cannot be used in a 'global using static' directive. // global using static C; Diagnostic(ErrorCode.ERR_GlobalUsingStaticFileType, "C").WithArguments("C").WithLocation(1, 21), // (5,9): error CS0103: The name 'M' does not exist in the current context @@ -2408,7 +2407,7 @@ public static void Main() // (1,1): hidden CS8019: Unnecessary using directive. // global using static Container; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "global using static Container;").WithLocation(1, 1), - // (1,21): error CS9304: File type 'Container' cannot be used in a 'global using static' directive. + // (1,21): error CS9055: File type 'Container' cannot be used in a 'global using static' directive. // global using static Container; Diagnostic(ErrorCode.ERR_GlobalUsingStaticFileType, "Container").WithArguments("Container").WithLocation(1, 21), // (5,9): error CS0103: The name 'M' does not exist in the current context @@ -2579,7 +2578,7 @@ public static void Main() // 'Derived.C' is not actually accessible from 'Program', so we just bind to 'Base.C'. var compilation = CreateCompilation(new[] { source, main }); compilation.VerifyDiagnostics( - // (16,20): error CS9303: File type 'Derived.C' must be defined in a top level type; 'Derived.C' is a nested type. + // (16,20): error CS9054: File type 'Derived.C' must be defined in a top level type; 'Derived.C' is a nested type. // new file class C Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Derived.C").WithLocation(16, 20)); @@ -2947,7 +2946,7 @@ class D : C1 { } // 1 var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (8,7): error CS9302: File type 'C' cannot be used as a base type of non-file type 'D'. + // (8,7): error CS9053: File type 'C' cannot be used as a base type of non-file type 'D'. // class D : C1 { } // 1 Diagnostic(ErrorCode.ERR_FileTypeBase, "D").WithArguments("NS.C", "NS.D").WithLocation(8, 7)); } @@ -3001,7 +3000,7 @@ public void Script_01() var comp = CreateSubmission(source1, parseOptions: TestOptions.Script.WithLanguageVersion(LanguageVersion.Preview)); comp.VerifyDiagnostics( - // (5,19): error CS9303: File type 'C1' must be defined in a top level type; 'C1' is a nested type. + // (5,19): error CS9054: File type 'C1' must be defined in a top level type; 'C1' is a nested type. // static file class C1 Diagnostic(ErrorCode.ERR_FileTypeNested, "C1").WithArguments("C1").WithLocation(5, 19), // (7,24): error CS1109: Extension methods must be defined in a top level static class; C1 is a nested class @@ -3015,7 +3014,7 @@ public void SystemVoid_01() var source1 = """ using System; - void M(Void v) { } // PROTOTYPE(ft): error here for explicit use of System.Void? + void M(Void v) { } namespace System { @@ -3023,10 +3022,12 @@ namespace System } """; + // https://github.com/dotnet/roslyn/issues/62331 + // Ideally we would give an error about use of System.Void here. var comp = CreateCompilation(source1); comp.VerifyDiagnostics( // (3,6): warning CS8321: The local function 'M' is declared but never used - // void M(Void v) { } // PROTOTYPE(ft): error here for explicit use of System.Void? + // void M(Void v) { } Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "M").WithArguments("M").WithLocation(3, 6)); var tree = comp.SyntaxTrees[0]; @@ -3109,7 +3110,7 @@ class Outer // from source var comp = CreateCompilation(source1); comp.VerifyDiagnostics( - // (3,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (3,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C { } // 1 Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16)); var sourceMember = comp.GetMember("Outer.C"); diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/FileModifierParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/FileModifierParsingTests.cs index 0f7fbe85446b8..4526b59797ae9 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/FileModifierParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/FileModifierParsingTests.cs @@ -192,7 +192,6 @@ public void FileModifier_03(SyntaxKind typeKeyword) EOF(); } - // PROTOTYPE(ft): is it fine that records parse as a single declaration here, but not other type kinds? [Theory] [InlineData(SyntaxKind.RecordKeyword)] public void FileModifier_04(SyntaxKind typeKeyword) @@ -239,7 +238,6 @@ public void FileModifier_05() EOF(); } - // PROTOTYPE(ft): is it fine that records parse here, but not other type kinds? [Fact] public void FileModifier_06() { @@ -332,22 +330,53 @@ public void FileModifier_07() UsingNode($$""" file partial ref struct C { } """, - // (1,14): error CS1585: Member modifier 'ref' must precede the member type and name - // file partial ref struct C { } - Diagnostic(ErrorCode.ERR_BadModifierLocation, "ref").WithArguments("ref").WithLocation(1, 14)); + expectedParsingDiagnostics: new[] + { + // (1,14): error CS1003: Syntax error, ',' expected + // file partial ref struct C { } + Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(1, 14), + // (1,18): error CS1002: ; expected + // file partial ref struct C { } + Diagnostic(ErrorCode.ERR_SemicolonExpected, "struct").WithLocation(1, 18) + }, + expectedBindingDiagnostics: new[] + { + // (1,1): error CS0246: The type or namespace name 'file' could not be found (are you missing a using directive or an assembly reference?) + // file partial ref struct C { } + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "file").WithArguments("file").WithLocation(1, 1), + // (1,6): warning CS0168: The variable 'partial' is declared but never used + // file partial ref struct C { } + Diagnostic(ErrorCode.WRN_UnreferencedVar, "partial").WithArguments("partial").WithLocation(1, 6), + // (1,14): error CS1003: Syntax error, ',' expected + // file partial ref struct C { } + Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(1, 14), + // (1,18): error CS1002: ; expected + // file partial ref struct C { } + Diagnostic(ErrorCode.ERR_SemicolonExpected, "struct").WithLocation(1, 18) + }); + N(SyntaxKind.CompilationUnit); { - N(SyntaxKind.IncompleteMember); + N(SyntaxKind.GlobalStatement); { - N(SyntaxKind.FileKeyword); - N(SyntaxKind.IdentifierName); + N(SyntaxKind.LocalDeclarationStatement); { - N(SyntaxKind.IdentifierToken, "partial"); + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "file"); + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "partial"); + } + } + M(SyntaxKind.SemicolonToken); } } N(SyntaxKind.StructDeclaration); { - N(SyntaxKind.RefKeyword); N(SyntaxKind.StructKeyword); N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.OpenBraceToken); @@ -478,7 +507,7 @@ public void FileModifier_11(SyntaxKind typeKeyword) """, expectedBindingDiagnostics: new[] { - // (1,20): error CS9301: File type 'C' cannot use accessibility modifiers. + // (1,20): error CS9052: File type 'C' cannot use accessibility modifiers. // public file {{SyntaxFacts.GetText(typeKeyword)}} C { } Diagnostic(ErrorCode.ERR_FileTypeNoExplicitAccessibility, "C").WithArguments("C") }); @@ -511,7 +540,7 @@ public void FileModifier_12(SyntaxKind typeKeyword) """, expectedBindingDiagnostics: new[] { - // (1,19): error CS9301: File type 'C' cannot use accessibility modifiers. + // (1,19): error CS9052: File type 'C' cannot use accessibility modifiers. // file public {{SyntaxFacts.GetText(typeKeyword)}} C { } Diagnostic(ErrorCode.ERR_FileTypeNoExplicitAccessibility, "C").WithArguments("C") }); @@ -667,7 +696,7 @@ class Outer """, expectedBindingDiagnostics: new[] { - // (3,16): error CS9303: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. + // (3,16): error CS9054: File type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type. // file class C { } Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16) }); @@ -1211,9 +1240,9 @@ public void MemberNamedFile_05() """, expectedBindingDiagnostics: new[] { - // (1,12): warning CS8981: The type name 'file' only contains lower-cased ascii characters. Such names may become reserved for the language. + // (1,12): error CS9056: Types and aliases cannot be named 'file'. // file class file { } - Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "file").WithArguments("file").WithLocation(1, 12) + Diagnostic(ErrorCode.ERR_FileTypeNameDisallowed, "file").WithLocation(1, 12) }); N(SyntaxKind.CompilationUnit); @@ -1366,7 +1395,6 @@ class C EOF(); } - // PROTOTYPE(ft): confirm with LDM whether this breaking change is acceptable (compared to CSharp10 version above). [Fact] public void MemberNamedFile_07() { @@ -1407,6 +1435,7 @@ class C } EOF(); } + [Fact] public void MemberNamedFile_08() { @@ -1415,9 +1444,9 @@ record file { } """, expectedBindingDiagnostics: new[] { - // (1,8): warning CS8981: The type name 'file' only contains lower-cased ascii characters. Such names may become reserved for the language. + // (1,8): error CS9056: Types and aliases cannot be named 'file'. // record file { } - Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "file").WithArguments("file").WithLocation(1, 8) + Diagnostic(ErrorCode.ERR_FileTypeNameDisallowed, "file").WithLocation(1, 8) }); N(SyntaxKind.CompilationUnit); @@ -1434,6 +1463,85 @@ record file { } EOF(); } + [Fact] + public void TypeNamedFile_01() + { + UsingNode($$""" + class file { } + """, + expectedBindingDiagnostics: new[] + { + // (1,7): error CS9056: Types and aliases cannot be named 'file'. + // class file { } + Diagnostic(ErrorCode.ERR_FileTypeNameDisallowed, "file").WithLocation(1, 7) + }); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "file"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void TypeNamedFile_01_CSharp10() + { + UsingNode($$""" + class file { } + """, + options: TestOptions.Regular10, + expectedBindingDiagnostics: new[] + { + // (1,7): warning CS8981: The type name 'file' only contains lower-cased ascii characters. Such names may become reserved for the language. + // class file { } + Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "file").WithArguments("file").WithLocation(1, 7) + }); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "file"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Theory] + [InlineData(LanguageVersion.CSharp10)] + [InlineData(LanguageVersionFacts.CSharpNext)] + public void TypeNamedFile_02(LanguageVersion languageVersion) + { + UsingNode($$""" + class @file { } + """, + options: TestOptions.Regular.WithLanguageVersion(languageVersion)); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "@file"); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + [Fact] public void Errors_01_CSharp10() { @@ -1473,7 +1581,10 @@ public void Errors_01() { N(SyntaxKind.IncompleteMember); { - N(SyntaxKind.FileKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "file"); + } } N(SyntaxKind.EndOfFileToken); } @@ -1521,32 +1632,26 @@ public void Errors_02() UsingNode($$""" file; """, - expectedParsingDiagnostics: new[] - { - // (1,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements - // file; - Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "file").WithLocation(1, 1) - }, expectedBindingDiagnostics: new[] { - // (1,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements + // (1,1): error CS0103: The name 'file' does not exist in the current context // file; - Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "file").WithLocation(1, 1), - // (1,5): error CS8937: At least one top-level statement must be non-empty. + Diagnostic(ErrorCode.ERR_NameNotInContext, "file").WithArguments("file").WithLocation(1, 1), + // (1,1): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement // file; - Diagnostic(ErrorCode.ERR_SimpleProgramIsEmpty, ";").WithLocation(1, 5) + Diagnostic(ErrorCode.ERR_IllegalStatement, "file").WithLocation(1, 1) }); N(SyntaxKind.CompilationUnit); { - N(SyntaxKind.IncompleteMember); - { - N(SyntaxKind.FileKeyword); - } N(SyntaxKind.GlobalStatement); { - N(SyntaxKind.EmptyStatement); + N(SyntaxKind.ExpressionStatement); { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "file"); + } N(SyntaxKind.SemicolonToken); } } @@ -1607,18 +1712,33 @@ public void Errors_03() UsingNode($$""" file namespace NS; """, + expectedParsingDiagnostics: new[] + { + // (1,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements + // file namespace NS; + Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "file").WithLocation(1, 1) + }, expectedBindingDiagnostics: new[] { - // (1,1): error CS1671: A namespace declaration cannot have modifiers or attributes + // (1,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // file namespace NS; - Diagnostic(ErrorCode.ERR_BadModifiersOnNamespace, "file").WithLocation(1, 1) + Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "file").WithLocation(1, 1), + // (1,16): error CS8956: File-scoped namespace must precede all other members in a file. + // file namespace NS; + Diagnostic(ErrorCode.ERR_FileScopedNamespaceNotBeforeAllMembers, "NS").WithLocation(1, 16) }); N(SyntaxKind.CompilationUnit); { + N(SyntaxKind.IncompleteMember); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "file"); + } + } N(SyntaxKind.FileScopedNamespaceDeclaration); { - N(SyntaxKind.FileKeyword); N(SyntaxKind.NamespaceKeyword); N(SyntaxKind.IdentifierName); { @@ -1675,18 +1795,24 @@ public void Errors_04() UsingNode($$""" file namespace NS { } """, - expectedBindingDiagnostics: new[] + expectedParsingDiagnostics: new[] { - // (1,1): error CS1671: A namespace declaration cannot have modifiers or attributes + // (1,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // file namespace NS { } - Diagnostic(ErrorCode.ERR_BadModifiersOnNamespace, "file").WithLocation(1, 1) + Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "file").WithLocation(1, 1) }); N(SyntaxKind.CompilationUnit); { + N(SyntaxKind.IncompleteMember); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "file"); + } + } N(SyntaxKind.NamespaceDeclaration); { - N(SyntaxKind.FileKeyword); N(SyntaxKind.NamespaceKeyword); N(SyntaxKind.IdentifierName); { @@ -1704,7 +1830,7 @@ public void Errors_04() public void File_Repeated() { const int FileModifiersCount = 100000; - var manyFileModifiers = string.Join(" ", Enumerable.Repeat("file", FileModifiersCount)); + var manyFileModifiers = string.Join(" ", Enumerable.Repeat("file", FileModifiersCount)); UsingNode(manyFileModifiers, expectedParsingDiagnostics: new[] { @@ -1715,10 +1841,14 @@ public void File_Repeated() { N(SyntaxKind.IncompleteMember); { - for (var i = 0; i < FileModifiersCount; i++) + for (var i = 0; i < FileModifiersCount - 1; i++) { N(SyntaxKind.FileKeyword); } + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "file"); + } N(SyntaxKind.EndOfFileToken); } } @@ -2007,7 +2137,7 @@ class C """, expectedBindingDiagnostics: new[] { - // (3,17): error CS9303: File type 'C.X' must be defined in a top level type; 'C.X' is a nested type. + // (3,17): error CS9054: File type 'C.X' must be defined in a top level type; 'C.X' is a nested type. // file record X(); Diagnostic(ErrorCode.ERR_FileTypeNested, "X").WithArguments("C.X").WithLocation(3, 17) }); @@ -2105,7 +2235,7 @@ class C """, expectedBindingDiagnostics: new[] { - // (3,17): error CS9303: File type 'C.X' must be defined in a top level type; 'C.X' is a nested type. + // (3,17): error CS9054: File type 'C.X' must be defined in a top level type; 'C.X' is a nested type. // file record X() { } Diagnostic(ErrorCode.ERR_FileTypeNested, "X").WithArguments("C.X").WithLocation(3, 17) }); @@ -2200,7 +2330,7 @@ class C """, expectedBindingDiagnostics: new[] { - // (3,17): error CS9303: File type 'C.X' must be defined in a top level type; 'C.X' is a nested type. + // (3,17): error CS9054: File type 'C.X' must be defined in a top level type; 'C.X' is a nested type. // file record X; Diagnostic(ErrorCode.ERR_FileTypeNested, "X").WithArguments("C.X").WithLocation(3, 17) }); @@ -2377,14 +2507,15 @@ void M() EOF(); } - // PROTOTYPE(ft): confirm whether this breaking change is acceptable - [Fact] - public void TopLevelVariable_01_CSharp10() + [Theory] + [InlineData(LanguageVersion.CSharp10)] + [InlineData(LanguageVersionFacts.CSharpNext)] + public void TopLevelVariable_01(LanguageVersion languageVersion) { UsingNode(""" file file; """, - options: TestOptions.Regular10, + options: TestOptions.Regular.WithLanguageVersion(languageVersion), expectedBindingDiagnostics: new[] { // (1,1): error CS0118: 'file' is a variable but is used like a type @@ -2420,52 +2551,15 @@ public void TopLevelVariable_01_CSharp10() EOF(); } - [Fact] - public void TopLevelVariable_01() - { - UsingNode(""" - file file; - """, - expectedParsingDiagnostics: new[] - { - // (1,6): error CS0116: A namespace cannot directly contain members such as fields, methods or statements - // file file; - Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "file").WithLocation(1, 6) - }, - expectedBindingDiagnostics: new[] - { - // (1,6): error CS0116: A namespace cannot directly contain members such as fields, methods or statements - // file file; - Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "file").WithLocation(1, 6), - // (1,10): error CS8937: At least one top-level statement must be non-empty. - // file file; - Diagnostic(ErrorCode.ERR_SimpleProgramIsEmpty, ";").WithLocation(1, 10) - }); - N(SyntaxKind.CompilationUnit); - { - N(SyntaxKind.IncompleteMember); - { - N(SyntaxKind.FileKeyword); - N(SyntaxKind.FileKeyword); - } - N(SyntaxKind.GlobalStatement); - { - N(SyntaxKind.EmptyStatement); - { - N(SyntaxKind.SemicolonToken); - } - } - N(SyntaxKind.EndOfFileToken); - } - EOF(); - } - - [Fact] - public void TopLevelVariable_02() + [Theory] + [InlineData(LanguageVersion.CSharp10)] + [InlineData(LanguageVersionFacts.CSharpNext)] + public void TopLevelVariable_02(LanguageVersion languageVersion) { UsingNode(""" int file; """, + options: TestOptions.Regular.WithLanguageVersion(languageVersion), expectedBindingDiagnostics: new[] { // (1,5): warning CS0168: The variable 'file' is declared but never used @@ -2497,36 +2591,23 @@ public void TopLevelVariable_02() EOF(); } - [Fact] - public void TopLevelVariable_04() + [Theory] + [InlineData(LanguageVersion.CSharp10)] + [InlineData(LanguageVersionFacts.CSharpNext)] + public void TopLevelVariable_03(LanguageVersion languageVersion) { - // PROTOTYPE(ft): this should parse and compile without errors - // we will share a common solution with 'required' and 'scoped' here. UsingNode(""" bool file; file = true; """, - expectedParsingDiagnostics: new[] - { - // (2,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements - // file = true; - Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "file").WithLocation(2, 1), - // (2,6): error CS1525: Invalid expression term '=' - // file = true; - Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(2, 6) - }, + options: TestOptions.Regular.WithLanguageVersion(languageVersion), expectedBindingDiagnostics: new[] { - // (1,6): warning CS0168: The variable 'file' is declared but never used + // (1,6): warning CS0219: The variable 'file' is assigned but its value is never used // bool file; - Diagnostic(ErrorCode.WRN_UnreferencedVar, "file").WithArguments("file").WithLocation(1, 6), - // (2,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements - // file = true; - Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "file").WithLocation(2, 1), - // (2,6): error CS1525: Invalid expression term '=' - // file = true; - Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(2, 6) + Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "file").WithArguments("file").WithLocation(1, 6) }); + N(SyntaxKind.CompilationUnit); { N(SyntaxKind.GlobalStatement); @@ -2547,19 +2628,15 @@ public void TopLevelVariable_04() N(SyntaxKind.SemicolonToken); } } - N(SyntaxKind.IncompleteMember); - { - N(SyntaxKind.FileKeyword); - } N(SyntaxKind.GlobalStatement); { N(SyntaxKind.ExpressionStatement); { N(SyntaxKind.SimpleAssignmentExpression); { - M(SyntaxKind.IdentifierName); + N(SyntaxKind.IdentifierName); { - M(SyntaxKind.IdentifierToken); + N(SyntaxKind.IdentifierToken, "file"); } N(SyntaxKind.EqualsToken); N(SyntaxKind.TrueLiteralExpression); @@ -2575,6 +2652,85 @@ public void TopLevelVariable_04() EOF(); } + [Fact] + public void Variable_01() + { + UsingNode(""" + void M() + { + bool file; + file = true; + } + """, + expectedBindingDiagnostics: new[] + { + // (1,6): warning CS8321: The local function 'M' is declared but never used + // void M() + Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "M").WithArguments("M").WithLocation(1, 6), + // (3,10): warning CS0219: The variable 'file' is assigned but its value is never used + // bool file; + Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "file").WithArguments("file").WithLocation(3, 10) + }); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.GlobalStatement); + { + N(SyntaxKind.LocalFunctionStatement); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.VoidKeyword); + } + N(SyntaxKind.IdentifierToken, "M"); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.LocalDeclarationStatement); + { + N(SyntaxKind.VariableDeclaration); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.BoolKeyword); + } + N(SyntaxKind.VariableDeclarator); + { + N(SyntaxKind.IdentifierToken, "file"); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.ExpressionStatement); + { + N(SyntaxKind.SimpleAssignmentExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "file"); + } + N(SyntaxKind.EqualsToken); + N(SyntaxKind.TrueLiteralExpression); + { + N(SyntaxKind.TrueKeyword); + } + } + N(SyntaxKind.SemicolonToken); + } + N(SyntaxKind.CloseBraceToken); + } + } + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + [Fact] public void LambdaReturn() { diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index bf7b9db988916..7018e80cb367a 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -111,4 +111,5 @@ virtual Microsoft.CodeAnalysis.SymbolVisitor.VisitPointerTyp virtual Microsoft.CodeAnalysis.SymbolVisitor.VisitProperty(Microsoft.CodeAnalysis.IPropertySymbol! symbol, TArgument argument) -> TResult virtual Microsoft.CodeAnalysis.SymbolVisitor.VisitRangeVariable(Microsoft.CodeAnalysis.IRangeVariableSymbol! symbol, TArgument argument) -> TResult virtual Microsoft.CodeAnalysis.SymbolVisitor.VisitTypeParameter(Microsoft.CodeAnalysis.ITypeParameterSymbol! symbol, TArgument argument) -> TResult -Microsoft.CodeAnalysis.Operations.BinaryOperatorKind.UnsignedRightShift = 25 -> Microsoft.CodeAnalysis.Operations.BinaryOperatorKind \ No newline at end of file +Microsoft.CodeAnalysis.Operations.BinaryOperatorKind.UnsignedRightShift = 25 -> Microsoft.CodeAnalysis.Operations.BinaryOperatorKind +Microsoft.CodeAnalysis.INamedTypeSymbol.IsFile.get -> bool \ No newline at end of file diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/EEMethodBinder.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/EEMethodBinder.cs index 1b075b464548e..c7b5cc398148e 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/EEMethodBinder.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/EEMethodBinder.cs @@ -44,7 +44,7 @@ internal EEMethodBinder(EEMethodSymbol method, MethodSymbol containingMethod, Bi var substitutedSourceMethod = method.SubstitutedSourceMethod; _parameterOffset = substitutedSourceMethod.IsStatic ? 0 : 1; _targetParameters = method.Parameters; - // PROTOTYPE(ft): add tests and adjust implementation to allow EE to access file types + // https://github.com/dotnet/roslyn/issues/62334: add tests and adjust implementation to allow EE to access file types _sourceBinder = new InMethodBinder(substitutedSourceMethod, new BuckStopsHereBinder(next.Compilation, associatedSyntaxTree: null)); } diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs index 94269b757bd9c..c29de94be92eb 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs @@ -706,7 +706,7 @@ private static bool IsAssignableExpression(Binder binder, BoundExpression expres @namespace = @namespace.ContainingNamespace; } - // PROTOTYPE(ft): add tests and adjust implementation to allow EE to access file types + // https://github.com/dotnet/roslyn/issues/62334: add tests and adjust implementation to allow EE to access file types Binder binder = new BuckStopsHereBinder(compilation, associatedSyntaxTree: null); var hasImports = !importRecordGroups.IsDefaultOrEmpty; var numImportStringGroups = hasImports ? importRecordGroups.Length : 0; diff --git a/src/Workspaces/Core/Portable/PublicAPI.Unshipped.txt b/src/Workspaces/Core/Portable/PublicAPI.Unshipped.txt index 33861f0f5b2f4..107531883f1ae 100644 --- a/src/Workspaces/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Workspaces/Core/Portable/PublicAPI.Unshipped.txt @@ -4,6 +4,8 @@ Microsoft.CodeAnalysis.CodeFixes.FixAllScope.ContainingMember = 4 -> Microsoft.C Microsoft.CodeAnalysis.CodeFixes.FixAllScope.ContainingType = 5 -> Microsoft.CodeAnalysis.CodeFixes.FixAllScope Microsoft.CodeAnalysis.Editing.DeclarationModifiers.IsRequired.get -> bool Microsoft.CodeAnalysis.Editing.DeclarationModifiers.WithIsRequired(bool isRequired) -> Microsoft.CodeAnalysis.Editing.DeclarationModifiers +Microsoft.CodeAnalysis.Editing.DeclarationModifiers.IsFile.get -> bool +Microsoft.CodeAnalysis.Editing.DeclarationModifiers.WithIsFile(bool isFile) -> Microsoft.CodeAnalysis.Editing.DeclarationModifiers Microsoft.CodeAnalysis.Editing.SyntaxEditor.SyntaxEditor(Microsoft.CodeAnalysis.SyntaxNode root, Microsoft.CodeAnalysis.Host.HostWorkspaceServices services) -> void *REMOVED*static Microsoft.CodeAnalysis.Editing.SyntaxGenerator.DefaultRemoveOptions -> Microsoft.CodeAnalysis.SyntaxRemoveOptions Microsoft.CodeAnalysis.TextDocumentEventArgs @@ -16,6 +18,7 @@ Microsoft.CodeAnalysis.Workspace.TextDocumentOpened -> System.EventHandler System.Collections.Immutable.ImmutableArray static Microsoft.CodeAnalysis.CodeFixes.FixAllProvider.Create(System.Func, System.Threading.Tasks.Task> fixAllAsync, System.Collections.Immutable.ImmutableArray supportedFixAllScopes) -> Microsoft.CodeAnalysis.CodeFixes.FixAllProvider static Microsoft.CodeAnalysis.Editing.DeclarationModifiers.Required.get -> Microsoft.CodeAnalysis.Editing.DeclarationModifiers +static Microsoft.CodeAnalysis.Editing.DeclarationModifiers.File.get -> Microsoft.CodeAnalysis.Editing.DeclarationModifiers static Microsoft.CodeAnalysis.Recommendations.Recommender.GetRecommendedSymbolsAtPositionAsync(Microsoft.CodeAnalysis.Document document, int position, Microsoft.CodeAnalysis.Options.OptionSet options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task> static readonly Microsoft.CodeAnalysis.Editing.SyntaxGenerator.DefaultRemoveOptions -> Microsoft.CodeAnalysis.SyntaxRemoveOptions Microsoft.CodeAnalysis.Rename.SymbolRenameOptions