From 6ebb7b0f92fe37bb001d3ee27e7ef897845e8f1e Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 12 Apr 2020 12:24:32 -0400 Subject: [PATCH 01/35] Planned diagnostics --- .../CSharp/Portable/CSharpResources.resx | 18 +++++++++++ .../CSharp/Portable/Errors/ErrorCode.cs | 7 +++++ .../Portable/xlf/CSharpResources.cs.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.de.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.es.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.fr.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.it.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.ja.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.ko.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.pl.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.pt-BR.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.ru.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.tr.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.zh-Hans.xlf | 30 +++++++++++++++++++ .../Portable/xlf/CSharpResources.zh-Hant.xlf | 30 +++++++++++++++++++ 15 files changed, 415 insertions(+) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index c7eee212e5687..7b62be7fff4c2 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -6073,4 +6073,22 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ module initializers + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + Module initializer method '{0}' must be static + + + Module initializer method '{0}' must not be contained in a generic type + + + Module initializer method '{0}' must not have generic parameters + + + Module initializer method '{0}' must not have parameters + + + Module initializer method '{0}' must return void + \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 548ce34a91b1f..eaa1cf4e421ca 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1777,6 +1777,13 @@ internal enum ErrorCode ERR_ExpressionTreeContainsFromEndIndexExpression = 8791, ERR_ExpressionTreeContainsRangeExpression = 8792, + ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType = 8793, + ERR_ModuleInitializerMethodMustBeStatic = 8794, + ERR_ModuleInitializerMethodMustNotHaveParameters = 8795, + ERR_ModuleInitializerMethodMustReturnVoid = 8796, + ERR_ModuleInitializerMethodMustNotBeGeneric = 8797, + ERR_ModuleInitializerMethodMustNotBeContainedInGenericType = 8798, + // Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd) } } diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index d99d9f87d50bc..e84a98d432b1e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -327,6 +327,36 @@ Chybějící vzor + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). Ve stejném adresáři nemůže být více konfiguračních souborů analyzátoru ({0}). diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index fbf7625e8ad87..c74368669ef99 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -327,6 +327,36 @@ Muster fehlt. + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). Dasselbe Verzeichnis ({0}) darf nicht mehrere Konfigurationsdateien des Analysetools enthalten. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index c71d7b59e9882..ee3174833d6a8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -327,6 +327,36 @@ Falta un patrón. + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). No es posible que un mismo directorio ("{0}") contenga varios archivos de configuración del analizador. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index c381951541e58..aec20901723d3 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -327,6 +327,36 @@ Modèle manquant + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). Plusieurs fichiers config d'analyseur ne peuvent pas figurer dans le même répertoire ('{0}'). diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 3c74d409c59e5..ab59a561ba07c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -327,6 +327,36 @@ Criterio mancante + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). La stessa directory ('{0}') non può contenere più file di configurazione dell'analizzatore. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 1c448e377867c..7c61feacb59c3 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -327,6 +327,36 @@ パターンがありません + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). 複数のアナライザー構成ファイルを同じディレクトリに入れることはできません ('{0}')。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 2a55ffc77840f..86d2392527d57 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -327,6 +327,36 @@ 패턴이 없습니다. + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). 분석기 구성 파일 여러 개가 동일한 디렉터리('{0}')에 있을 수 없습니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index d64fcc15e22a7..5f149de6a7a7e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -327,6 +327,36 @@ Brak wzorca + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). Wiele plików konfiguracji analizatora nie może znajdować się w tym samym katalogu („{0}”). diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index e4944db4ed774..ec3655b069639 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -327,6 +327,36 @@ Padrão ausente + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). Não é possível que haja vários arquivos de configuração do analisador no mesmo diretório ('{0}'). diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index a58a44f35c529..94f6fe1d13a2e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -327,6 +327,36 @@ Отсутствует шаблон + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). В одном каталоге ("{0}") не может находиться несколько файлов конфигурации анализатора. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 61ffc836a9555..71b49b334e966 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -327,6 +327,36 @@ Desen eksik + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). Birden çok çözümleyici yapılandırma dosyası aynı dizinde ('{0}') olamaz. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 1311c9a8a9891..ef964491c2c77 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -327,6 +327,36 @@ 模式缺失 + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). 多个分析器配置文件不能位于同一目录({0})中。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 743ae017dc580..11f9625edc55b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -327,6 +327,36 @@ 缺少模式 + + Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible outside top-level type '{1}' + + + + Module initializer method '{0}' must be static + Module initializer method '{0}' must be static + + + + Module initializer method '{0}' must not be contained in a generic type + Module initializer method '{0}' must not be contained in a generic type + + + + Module initializer method '{0}' must not have generic parameters + Module initializer method '{0}' must not have generic parameters + + + + Module initializer method '{0}' must not have parameters + Module initializer method '{0}' must not have parameters + + + + Module initializer method '{0}' must return void + Module initializer method '{0}' must return void + + Multiple analyzer config files cannot be in the same directory ('{0}'). 多個分析器組態檔無法處於相同目錄 ('{0}') 中。 From ad85620e3b25f75d24b356b66cd937f85a07831a Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 12 Apr 2020 12:35:27 -0400 Subject: [PATCH 02/35] Accessibility diagnostics --- .../SourceMethodSymbolWithAttributes.cs | 60 ++- .../ModuleInitializersTests.Accessibility.cs | 392 ++++++++++++++++++ .../Symbol/Symbols/ModuleInitializersTests.cs | 2 +- 3 files changed, 451 insertions(+), 3 deletions(-) create mode 100644 src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index f0f9672e4feb3..546b7293fdfa3 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Roslyn.Utilities; @@ -485,8 +486,7 @@ private void DecodeWellKnownAttributeAppliedToMethod(ref DecodeWellKnownAttribut else if (attribute.IsTargetAttribute(this, AttributeDescription.ModuleInitializerAttribute)) { MessageID.IDS_FeatureModuleInitializers.CheckFeatureAvailability(arguments.Diagnostics, arguments.AttributeSyntaxOpt); - // PROTOTYPE(module-initializers): diagnostics - DeclaringCompilation.AddModuleInitializerMethod(this); + DecodeModuleInitializerAttribute(arguments); } else { @@ -763,6 +763,62 @@ private void DecodeDllImportAttribute(ref DecodeWellKnownAttributeArguments arguments) + { + Debug.Assert(arguments.AttributeSyntaxOpt is object); + + if (isInaccessible(this) || anyContainingTypeIsInaccessible(this)) + { + var topLevelType = getTopLevelContainingType(this); + Debug.Assert(topLevelType is object); + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, arguments.AttributeSyntaxOpt.Location, Name, topLevelType.Name); + } + + DeclaringCompilation.AddModuleInitializerMethod(this); + + static bool isInaccessible(Symbol symbol) + { + switch (symbol.DeclaredAccessibility) + { + case Accessibility.Private: + case Accessibility.Protected: + case Accessibility.ProtectedAndInternal: + return true; + default: + return false; + } + } + + static bool anyContainingTypeIsInaccessible(Symbol symbol) + { + for (; symbol.ContainingType is { } type; symbol = type) + { + if (isInaccessible(type)) + { + return true; + } + } + + return false; + } + + static TypeSymbol? getTopLevelContainingType(Symbol symbol) + { + var type = symbol.ContainingType; + if (type is null) + { + return null; + } + + while (type.ContainingType is { } containingType) + { + type = containingType; + } + + return type; + } + } #nullable restore internal sealed override void PostDecodeWellKnownAttributes(ImmutableArray boundAttributes, ImmutableArray allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs new file mode 100644 index 0000000000000..bdcd35157edd5 --- /dev/null +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs @@ -0,0 +1,392 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +{ + public sealed partial class ModuleInitializersTests + { + [Fact] + public void VisibilityMustNotBePrivate() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + private static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) + ); + } + + [Fact] + public void VisibilityMustNotBeProtected() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + protected static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) + ); + } + + [Fact] + public void VisibilityMustNotBePrivateProtected() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + private protected static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) + ); + } + + [Fact] + public void VisibilityMayBePublic() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + + [Fact] + public void VisibilityMayBeInternal() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + internal static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + + [Fact] + public void VisibilityMayBeProtectedInternal() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + protected internal static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + + [Fact] + public void TopLevelTypeMayBeInternal() + { + string source = @" +using System.Runtime.CompilerServices; + +internal class C +{ + [ModuleInitializer] + public static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + + [Fact] + public void TopLevelTypeMayBePublic() + { + string source = @" +using System.Runtime.CompilerServices; + +public class C +{ + [ModuleInitializer] + public static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + + [Fact] + public void NestedTypeVisibilityMustNotBePrivate() + { + string source = @" +using System.Runtime.CompilerServices; + +public class C +{ + private class Nested + { + [ModuleInitializer] + public static void M() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (8,10): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) + ); + } + + [Fact] + public void NestedTypeVisibilityMustNotBeProtected() + { + string source = @" +using System.Runtime.CompilerServices; + +public class C +{ + protected class Nested + { + [ModuleInitializer] + public static void M() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (8,10): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) + ); + } + + [Fact] + public void NestedTypeVisibilityMustNotBePrivateProtected() + { + string source = @" +using System.Runtime.CompilerServices; + +public class C +{ + private protected class Nested + { + [ModuleInitializer] + public static void M() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (8,10): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) + ); + } + + [Fact] + public void NestedTypeVisibilityMayBePublic() + { + string source = @" +using System.Runtime.CompilerServices; + +public class C +{ + public class Nested + { + [ModuleInitializer] + public static void M() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + + [Fact] + public void NestedTypeVisibilityMayBeInternal() + { + string source = @" +using System.Runtime.CompilerServices; + +public class C +{ + internal class Nested + { + [ModuleInitializer] + public static void M() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + + [Fact] + public void NestedTypeVisibilityMayBeProtectedInternal() + { + string source = @" +using System.Runtime.CompilerServices; + +public class C +{ + protected internal class Nested + { + [ModuleInitializer] + public static void M() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + + [Fact] + public void MayBeDeclaredByStruct() + { + string source = @" +using System.Runtime.CompilerServices; + +struct S +{ + [ModuleInitializer] + internal static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + + [Fact] + public void MayBeDeclaredByInterface() + { + string source = @" +using System.Runtime.CompilerServices; + +interface I +{ + [ModuleInitializer] + internal static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + + compilation.VerifyDiagnostics( + // (7,26): error CS8701: Target runtime doesn't support default interface implementation. + // internal static void M() { } + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M").WithLocation(7, 26) + ); + } + + [Fact] + public void ImplicitPublicInterfaceMethodVisibility() + { + string source = @" +using System.Runtime.CompilerServices; + +interface I +{ + [ModuleInitializer] + static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + + // Intentionally demonstrated without DIM support. + + compilation.VerifyDiagnostics( + // (7,17): error CS8701: Target runtime doesn't support default interface implementation. + // static void M() { } + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M").WithLocation(7, 17) + ); + } + + [Fact] + public void ImplicitPublicInterfaceNestedTypeVisibility() + { + string source = @" +using System.Runtime.CompilerServices; + +interface I +{ + class Nested + { + [ModuleInitializer] + internal static void M() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics(); + } + } +} diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index 558aab4d66028..69c962d3a5873 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -12,7 +12,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols { [CompilerTrait(CompilerFeature.ModuleInitializers)] - public sealed class ModuleInitializersTests : CSharpTestBase + public sealed partial class ModuleInitializersTests : CSharpTestBase { private static readonly CSharpParseOptions s_parseOptions = TestOptions.RegularPreview; From 37bcdeadf292d41f815e0c927f084007cb271990 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 12 Apr 2020 14:11:28 -0400 Subject: [PATCH 03/35] Signature diagnostics --- .../SourceMethodSymbolWithAttributes.cs | 15 ++ .../ModuleInitializersTests.Signature.cs | 168 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 546b7293fdfa3..6094489ab6b50 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -775,6 +775,21 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, arguments.AttributeSyntaxOpt.Location, Name, topLevelType.Name); } + if (!IsStatic) + { + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeStatic, arguments.AttributeSyntaxOpt.Location, Name); + } + + if (ParameterCount > 0) + { + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, arguments.AttributeSyntaxOpt.Location, Name); + } + + if (!ReturnsVoid) + { + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, arguments.AttributeSyntaxOpt.Location, Name); + } + DeclaringCompilation.AddModuleInitializerMethod(this); static bool isInaccessible(Symbol symbol) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs new file mode 100644 index 0000000000000..49a27bae97a7b --- /dev/null +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs @@ -0,0 +1,168 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +{ + public sealed partial class ModuleInitializersTests + { + [Fact] + public void MustNotBeInstanceMethod() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + internal void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8794: Module initializer method 'M' must be static + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStatic, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + ); + } + + [Fact] + public void MustNotHaveParameters() + { + string source = @" +using System.Runtime.CompilerServices; + +static class C +{ + [ModuleInitializer] + internal static void M(object p) { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8795: Module initializer method 'M' must not have parameters + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + ); + } + + [Fact] + public void MustNotHaveOptionalParameters() + { + string source = @" +using System.Runtime.CompilerServices; + +static class C +{ + [ModuleInitializer] + internal static void M(object p = null) { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8795: Module initializer method 'M' must not have parameters + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + ); + } + + [Fact] + public void MustNotHaveParamsArrayParameters() + { + string source = @" +using System.Runtime.CompilerServices; + +static class C +{ + [ModuleInitializer] + internal static void M(params object[] p) { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8795: Module initializer method 'M' must not have parameters + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + ); + } + + [Fact] + public void MustNotReturnAValue() + { + string source = @" +using System.Runtime.CompilerServices; + +static class C +{ + [ModuleInitializer] + internal static object M() => null; +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8796: Module initializer method 'M' must return void + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + ); + } + + [Fact] + public void MayBeAsyncVoid() + { + string source = @" +using System.Runtime.CompilerServices; + +static class C +{ + [ModuleInitializer] + internal static async void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (7,32): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. + // internal static async void M() { } + Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M").WithLocation(7, 32) + ); + } + + [Fact] + public void MayNotReturnAwaitableWithVoidResult() + { + string source = @" +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +static class C +{ + [ModuleInitializer] + internal static async Task M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (7,6): error CS8796: Module initializer method 'M' must return void + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, "ModuleInitializer").WithArguments("M").WithLocation(7, 6), + // (8,32): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. + // internal static async Task M() { } + Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M").WithLocation(8, 32)); + } + } +} From f6ee3212159a19e2e0ff1515bad879c4a792ba13 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 12 Apr 2020 14:19:19 -0400 Subject: [PATCH 04/35] Improve readability --- .../SourceMethodSymbolWithAttributes.cs | 31 +++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 6094489ab6b50..5df0f099af760 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -768,9 +768,9 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< { Debug.Assert(arguments.AttributeSyntaxOpt is object); - if (isInaccessible(this) || anyContainingTypeIsInaccessible(this)) + if (isInaccessible(this) || containingTypes(this).Any(isInaccessible)) { - var topLevelType = getTopLevelContainingType(this); + var topLevelType = containingTypes(this).LastOrDefault(); Debug.Assert(topLevelType is object); arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, arguments.AttributeSyntaxOpt.Location, Name, topLevelType.Name); } @@ -805,33 +805,12 @@ static bool isInaccessible(Symbol symbol) } } - static bool anyContainingTypeIsInaccessible(Symbol symbol) + static IEnumerable containingTypes(Symbol symbol) { - for (; symbol.ContainingType is { } type; symbol = type) + for (var type = symbol.ContainingType; type is { }; type = type.ContainingType) { - if (isInaccessible(type)) - { - return true; - } + yield return type; } - - return false; - } - - static TypeSymbol? getTopLevelContainingType(Symbol symbol) - { - var type = symbol.ContainingType; - if (type is null) - { - return null; - } - - while (type.ContainingType is { } containingType) - { - type = containingType; - } - - return type; } } #nullable restore From f1f5a38626511bf81619aa0b7c29be5ac1312083 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 12 Apr 2020 14:27:21 -0400 Subject: [PATCH 05/35] Generics diagnostics --- .../SourceMethodSymbolWithAttributes.cs | 14 +++- .../ModuleInitializersTests.Generics.cs | 80 +++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 5df0f099af760..7e71d8ae05e9f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -767,11 +767,11 @@ private void DecodeDllImportAttribute(ref DecodeWellKnownAttributeArguments arguments) { Debug.Assert(arguments.AttributeSyntaxOpt is object); + Debug.Assert(ContainingType is object); if (isInaccessible(this) || containingTypes(this).Any(isInaccessible)) { - var topLevelType = containingTypes(this).LastOrDefault(); - Debug.Assert(topLevelType is object); + var topLevelType = containingTypes(this).Last(); arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, arguments.AttributeSyntaxOpt.Location, Name, topLevelType.Name); } @@ -790,6 +790,16 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, arguments.AttributeSyntaxOpt.Location, Name); } + if (IsGenericMethod) + { + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustNotBeGeneric, arguments.AttributeSyntaxOpt.Location, Name); + } + + if (ContainingType.IsGenericType) + { + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, arguments.AttributeSyntaxOpt.Location, Name); + } + DeclaringCompilation.AddModuleInitializerMethod(this); static bool isInaccessible(Symbol symbol) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs new file mode 100644 index 0000000000000..5d29a5b2610a3 --- /dev/null +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +{ + public sealed partial class ModuleInitializersTests + { + [Fact] + public void MustNotBeGenericMethod() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + internal static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8797: Module initializer method 'M' must not have generic parameters + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeGeneric, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + ); + } + + [Fact] + public void MustNotBeContainedInGenericType() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + internal static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8797: Module initializer method 'M' must not be contained in a generic type + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + ); + } + + [Fact] + public void MustNotBeContainedInGenericTypeWithParametersDeclaredByContainingGenericType() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + internal class Nested + { + [ModuleInitializer] + internal static void M() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (8,10): error CS8798: Module initializer method 'M' must not be contained in a generic type + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, "ModuleInitializer").WithArguments("M").WithLocation(8, 10) + ); + } + } +} From 618d89a6ffa7fd8758e69bf16f5f2d769197a718 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 12 Apr 2020 16:01:35 -0400 Subject: [PATCH 06/35] Usages ignored without diagnostics --- .../SourceMethodSymbolWithAttributes.cs | 5 + .../ModuleInitializersTests.Ignored.cs | 440 ++++++++++++++++++ 2 files changed, 445 insertions(+) create mode 100644 src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 7e71d8ae05e9f..d248137a38000 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -766,6 +766,11 @@ private void DecodeDllImportAttribute(ref DecodeWellKnownAttributeArguments arguments) { + if (MethodKind != MethodKind.Ordinary) + { + return; + } + Debug.Assert(arguments.AttributeSyntaxOpt is object); Debug.Assert(ContainingType is object); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs new file mode 100644 index 0000000000000..3d4f15826301f --- /dev/null +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs @@ -0,0 +1,440 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +{ + public sealed partial class ModuleInitializersTests + { + [Fact] + public void IgnoredOnLocalFunction() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + internal static void M() + { + [ModuleInitializer] + static void LocalFunction() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnReturnValue() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [return: ModuleInitializer] + internal static void M() + { + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnMethodParameter() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + internal static void M([ModuleInitializer] int p) + { + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnGenericParameter() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + internal static void M<[ModuleInitializer] T>() + { + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnClass() + { + string source = @" +using System.Runtime.CompilerServices; + +[ModuleInitializer] +class C +{ + internal static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnStaticConstructor() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + static C() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnInstanceConstructor() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public C() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnDestructor() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + ~C() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnOperator() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public static C operator -(C p) => p; +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnConversionOperator() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public static explicit operator int(C p) => default; +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnEvent() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public event System.Action E; +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnEventAccessors() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + public event System.Action E + { + [ModuleInitializer] + add { } + [ModuleInitializer] + remove { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnProperty() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public int P { get; set; } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnPropertyAccessors() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + public int P + { + [ModuleInitializer] + get; + [ModuleInitializer] + set; + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnIndexer() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public int this[int p] => p; +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnIndexerAccessors() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + public int this[int p] + { + [ModuleInitializer] + get => p; + [ModuleInitializer] + set { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnField() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public int F; +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnModule() + { + string source = @" +using System.Runtime.CompilerServices; + +[module: ModuleInitializer] + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredOnAssembly() + { + string source = @" +using System.Runtime.CompilerServices; + +[assembly: ModuleInitializer] + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredWhenConstructorArgumentIsSpecified() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer(42)] + internal static void M() + { + } +} + +namespace System.Runtime.CompilerServices +{ + class ModuleInitializerAttribute : System.Attribute + { + public ModuleInitializerAttribute(int p) { } + } +} +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + + [Fact] + public void IgnoredWhenNamedArgumentIsSpecified() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer(P = 42)] + internal static void M() + { + } +} + +namespace System.Runtime.CompilerServices +{ + class ModuleInitializerAttribute : System.Attribute + { + public int P { get; set; } + } +} +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyMemberInIL("..cctor", expected: false); + } + } +} From 0ae310f299defb9e208f82e6553d1d3d1bcde243 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 12 Apr 2020 16:11:14 -0400 Subject: [PATCH 07/35] Multiple application is ignored --- .../Symbol/Symbols/ModuleInitializersTests.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index 69c962d3a5873..fa07332b6eb3a 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -137,5 +137,37 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S C.M Program.Main"); } + + [Fact] + public void SingleCallIsGeneratedWhenMethodIsMarkedTwice() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer, ModuleInitializer] + internal static void M() { } +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + class ModuleInitializerAttribute : Attribute + { + } +} +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyIL("..cctor", @" +{ + // Code size 6 (0x6) + .maxstack 0 + IL_0000: call ""void C.M()"" + IL_0005: ret +}"); + } } } From fb425a88eb72427aef4c833aa77f941d18e010f5 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sun, 12 Apr 2020 17:19:09 -0400 Subject: [PATCH 08/35] Couple more valid cases --- .../Symbol/Symbols/ModuleInitializersTests.cs | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index fa07332b6eb3a..d877ec70db19c 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -167,6 +167,56 @@ class ModuleInitializerAttribute : Attribute .maxstack 0 IL_0000: call ""void C.M()"" IL_0005: ret +}"); + } + + [Fact] + public void AttributeCanBeAppliedWithinItsOwnDefinition() + { + string source = @" +namespace System.Runtime.CompilerServices +{ + class ModuleInitializerAttribute : System.Attribute + { + [ModuleInitializer] + internal static void M() { } + } +} +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyIL("..cctor", @" +{ + // Code size 6 (0x6) + .maxstack 0 + IL_0000: call ""void System.Runtime.CompilerServices.ModuleInitializerAttribute.M()"" + IL_0005: ret +}"); + } + + [Fact] + public void ExternMethodCanBeModuleInitializer() + { + string source = @" +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +class C +{ + [ModuleInitializer, DllImport(""foo"")] + internal static extern void M(); +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); + + verifier.VerifyIL("..cctor", @" +{ + // Code size 6 (0x6) + .maxstack 0 + IL_0000: call ""void C.M()"" + IL_0005: ret }"); } } From 31530609b134879f33fd132072394e17b2f8120f Mon Sep 17 00:00:00 2001 From: jnm2 Date: Tue, 14 Apr 2020 22:13:22 -0400 Subject: [PATCH 09/35] Diagnostic to cover the gap left by AttributeTargets.Method --- src/Compilers/CSharp/Portable/CSharpResources.resx | 3 +++ src/Compilers/CSharp/Portable/Errors/ErrorCode.cs | 13 +++++++------ .../CSharp/Portable/xlf/CSharpResources.cs.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.de.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.es.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.fr.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.it.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.ja.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.ko.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.pl.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.pt-BR.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.ru.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.tr.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf | 5 +++++ .../ModuleInitializersTests.Accessibility.cs | 12 ++++++------ .../Symbols/ModuleInitializersTests.Generics.cs | 6 +++--- .../Symbols/ModuleInitializersTests.Signature.cs | 12 ++++++------ 18 files changed, 90 insertions(+), 21 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 7b62be7fff4c2..46dd147185689 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -6091,4 +6091,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Module initializer method '{0}' must return void + + A module initializer must be an ordinary method + \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index eaa1cf4e421ca..19d0e8e343f13 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1777,12 +1777,13 @@ internal enum ErrorCode ERR_ExpressionTreeContainsFromEndIndexExpression = 8791, ERR_ExpressionTreeContainsRangeExpression = 8792, - ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType = 8793, - ERR_ModuleInitializerMethodMustBeStatic = 8794, - ERR_ModuleInitializerMethodMustNotHaveParameters = 8795, - ERR_ModuleInitializerMethodMustReturnVoid = 8796, - ERR_ModuleInitializerMethodMustNotBeGeneric = 8797, - ERR_ModuleInitializerMethodMustNotBeContainedInGenericType = 8798, + ERR_ModuleInitializerMethodMustBeOrdinary = 8793, + ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType = 8794, + ERR_ModuleInitializerMethodMustBeStatic = 8795, + ERR_ModuleInitializerMethodMustNotHaveParameters = 8796, + ERR_ModuleInitializerMethodMustReturnVoid = 8797, + ERR_ModuleInitializerMethodMustNotBeGeneric = 8798, + ERR_ModuleInitializerMethodMustNotBeContainedInGenericType = 8799, // Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd) } diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index e84a98d432b1e..41d62413778e3 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index c74368669ef99..26fe59f368cd4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index ee3174833d6a8..7e77b08dbef5a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index aec20901723d3..7415b8d5c93a2 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index ab59a561ba07c..84b2b31c43916 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 7c61feacb59c3..ada6a7f816cf0 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 86d2392527d57..11f0bf2c953ac 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 5f149de6a7a7e..afbe60e014ac1 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index ec3655b069639..8820d3a259e29 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 94f6fe1d13a2e..ee071dd5fc2c5 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 71b49b334e966..3cb970c35ea91 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index ef964491c2c77..8cd2d4c2992f1 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 11f9625edc55b..d762f8d0b0f85 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -332,6 +332,11 @@ Module initializer method '{0}' must be accessible outside top-level type '{1}' + + A module initializer must be an ordinary method + A module initializer must be an ordinary method + + Module initializer method '{0}' must be static Module initializer method '{0}' must be static diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs index bdcd35157edd5..11d01bc0317b3 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs @@ -24,7 +24,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // (6,6): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) ); @@ -46,7 +46,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // (6,6): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) ); @@ -68,7 +68,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // (6,6): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) ); @@ -183,7 +183,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (8,10): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // (8,10): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) ); @@ -208,7 +208,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (8,10): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // (8,10): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) ); @@ -233,7 +233,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (8,10): error CS8793: Module initializer method 'M' must be accessible outside top-level type 'C' + // (8,10): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) ); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs index 5d29a5b2610a3..9ae63b710e85b 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs @@ -24,7 +24,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8797: Module initializer method 'M' must not have generic parameters + // (6,6): error CS8798: Module initializer method 'M' must not have generic parameters // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeGeneric, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); @@ -46,7 +46,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8797: Module initializer method 'M' must not be contained in a generic type + // (6,6): error CS8798: Module initializer method 'M' must not be contained in a generic type // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); @@ -71,7 +71,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (8,10): error CS8798: Module initializer method 'M' must not be contained in a generic type + // (8,10): error CS8799: Module initializer method 'M' must not be contained in a generic type // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, "ModuleInitializer").WithArguments("M").WithLocation(8, 10) ); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs index 49a27bae97a7b..71913d276366f 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs @@ -24,7 +24,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8794: Module initializer method 'M' must be static + // (6,6): error CS8795: Module initializer method 'M' must be static // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStatic, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); @@ -46,7 +46,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8795: Module initializer method 'M' must not have parameters + // (6,6): error CS8796: Module initializer method 'M' must not have parameters // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); @@ -68,7 +68,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8795: Module initializer method 'M' must not have parameters + // (6,6): error CS8796: Module initializer method 'M' must not have parameters // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); @@ -90,7 +90,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8795: Module initializer method 'M' must not have parameters + // (6,6): error CS8796: Module initializer method 'M' must not have parameters // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); @@ -112,7 +112,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (6,6): error CS8796: Module initializer method 'M' must return void + // (6,6): error CS8797: Module initializer method 'M' must return void // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); @@ -157,7 +157,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyDiagnostics( - // (7,6): error CS8796: Module initializer method 'M' must return void + // (7,6): error CS8797: Module initializer method 'M' must return void // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, "ModuleInitializer").WithArguments("M").WithLocation(7, 6), // (8,32): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. From 3255afaa9efd6e6deac635160fdddf122003732c Mon Sep 17 00:00:00 2001 From: jnm2 Date: Tue, 14 Apr 2020 22:33:18 -0400 Subject: [PATCH 10/35] Cover the gap left by AttributeTargets.Method --- .../SourceMethodSymbolWithAttributes.cs | 9 +- .../ModuleInitializersTests.Ignored.cs | 151 -------------- .../ModuleInitializersTests.Targets.cs | 193 ++++++++++++++++++ 3 files changed, 201 insertions(+), 152 deletions(-) create mode 100644 src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index d248137a38000..4e21bce9272ba 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -766,12 +766,19 @@ private void DecodeDllImportAttribute(ref DecodeWellKnownAttributeArguments arguments) { + Debug.Assert(arguments.AttributeSyntaxOpt is object); + if (MethodKind != MethodKind.Ordinary) { + // Ignore cases where there will already be a warning due to the AttributeTargets.Method usage + // restriction on the attribute definition in the framework. + if (MethodKind != MethodKind.Constructor && MethodKind != MethodKind.StaticConstructor) + { + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, arguments.AttributeSyntaxOpt.Location); + } return; } - Debug.Assert(arguments.AttributeSyntaxOpt is object); Debug.Assert(ContainingType is object); if (isInaccessible(this) || containingTypes(this).Any(isInaccessible)) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs index 3d4f15826301f..bd382a8fccdcb 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs @@ -8,28 +8,6 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols { public sealed partial class ModuleInitializersTests { - [Fact] - public void IgnoredOnLocalFunction() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - internal static void M() - { - [ModuleInitializer] - static void LocalFunction() { } - } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); - } - [Fact] public void IgnoredOnReturnValue() { @@ -141,63 +119,6 @@ class C public C() { } } -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); - } - - [Fact] - public void IgnoredOnDestructor() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer] - ~C() { } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); - } - - [Fact] - public void IgnoredOnOperator() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer] - public static C operator -(C p) => p; -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); - } - - [Fact] - public void IgnoredOnConversionOperator() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer] - public static explicit operator int(C p) => default; -} - namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); @@ -217,30 +138,6 @@ class C public event System.Action E; } -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); - } - - [Fact] - public void IgnoredOnEventAccessors() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - public event System.Action E - { - [ModuleInitializer] - add { } - [ModuleInitializer] - remove { } - } -} - namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); @@ -260,30 +157,6 @@ class C public int P { get; set; } } -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); - } - - [Fact] - public void IgnoredOnPropertyAccessors() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - public int P - { - [ModuleInitializer] - get; - [ModuleInitializer] - set; - } -} - namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); @@ -303,30 +176,6 @@ class C public int this[int p] => p; } -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); - } - - [Fact] - public void IgnoredOnIndexerAccessors() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - public int this[int p] - { - [ModuleInitializer] - get => p; - [ModuleInitializer] - set { } - } -} - namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs new file mode 100644 index 0000000000000..c9d4f619a8564 --- /dev/null +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs @@ -0,0 +1,193 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +{ + public sealed partial class ModuleInitializersTests + { + [Fact] + public void IgnoredOnLocalFunction() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + internal static void M() + { + LocalFunction(); + [ModuleInitializer] + static void LocalFunction() { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (9,10): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(9, 10) + ); + } + + [Fact] + public void IgnoredOnDestructor() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + ~C() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) + ); + } + + [Fact] + public void IgnoredOnOperator() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public static C operator -(C p) => p; +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) + ); + } + + [Fact] + public void IgnoredOnConversionOperator() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public static explicit operator int(C p) => default; +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (6,6): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) + ); + } + + [Fact] + public void IgnoredOnEventAccessors() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + public event System.Action E + { + [ModuleInitializer] + add { } + [ModuleInitializer] + remove { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (8,10): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(8, 10), + // (10,10): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(10, 10) + ); + } + + [Fact] + public void IgnoredOnPropertyAccessors() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + public int P + { + [ModuleInitializer] + get; + [ModuleInitializer] + set; + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (8,10): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(8, 10), + // (10,10): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(10, 10) + ); + } + + [Fact] + public void IgnoredOnIndexerAccessors() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + public int this[int p] + { + [ModuleInitializer] + get => p; + [ModuleInitializer] + set { } + } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyDiagnostics( + // (8,10): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(8, 10), + // (10,10): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(10, 10) + ); + } + } +} From 724d23d8194612a0d28002fb35c20803b2737085 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 18:00:39 -0400 Subject: [PATCH 11/35] =?UTF-8?q?'Visibility'=20=E2=86=92=20'Accessibility?= =?UTF-8?q?'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ModuleInitializersTests.Accessibility.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs index 11d01bc0317b3..a56c452c355eb 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols public sealed partial class ModuleInitializersTests { [Fact] - public void VisibilityMustNotBePrivate() + public void AccessibilityMustNotBePrivate() { string source = @" using System.Runtime.CompilerServices; @@ -31,7 +31,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void VisibilityMustNotBeProtected() + public void AccessibilityMustNotBeProtected() { string source = @" using System.Runtime.CompilerServices; @@ -53,7 +53,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void VisibilityMustNotBePrivateProtected() + public void AccessibilityMustNotBePrivateProtected() { string source = @" using System.Runtime.CompilerServices; @@ -75,7 +75,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void VisibilityMayBePublic() + public void AccessibilityMayBePublic() { string source = @" using System.Runtime.CompilerServices; @@ -93,7 +93,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void VisibilityMayBeInternal() + public void AccessibilityMayBeInternal() { string source = @" using System.Runtime.CompilerServices; @@ -111,7 +111,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void VisibilityMayBeProtectedInternal() + public void AccessibilityMayBeProtectedInternal() { string source = @" using System.Runtime.CompilerServices; @@ -165,7 +165,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void NestedTypeVisibilityMustNotBePrivate() + public void NestedTypeAccessibilityMustNotBePrivate() { string source = @" using System.Runtime.CompilerServices; @@ -190,7 +190,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void NestedTypeVisibilityMustNotBeProtected() + public void NestedTypeAccessibilityMustNotBeProtected() { string source = @" using System.Runtime.CompilerServices; @@ -215,7 +215,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void NestedTypeVisibilityMustNotBePrivateProtected() + public void NestedTypeAccessibilityMustNotBePrivateProtected() { string source = @" using System.Runtime.CompilerServices; @@ -240,7 +240,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void NestedTypeVisibilityMayBePublic() + public void NestedTypeAccessibilityMayBePublic() { string source = @" using System.Runtime.CompilerServices; @@ -261,7 +261,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void NestedTypeVisibilityMayBeInternal() + public void NestedTypeAccessibilityMayBeInternal() { string source = @" using System.Runtime.CompilerServices; @@ -282,7 +282,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void NestedTypeVisibilityMayBeProtectedInternal() + public void NestedTypeAccessibilityMayBeProtectedInternal() { string source = @" using System.Runtime.CompilerServices; @@ -344,7 +344,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void ImplicitPublicInterfaceMethodVisibility() + public void ImplicitPublicInterfaceMethodAccessibility() { string source = @" using System.Runtime.CompilerServices; @@ -369,7 +369,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void ImplicitPublicInterfaceNestedTypeVisibility() + public void ImplicitPublicInterfaceNestedTypeAccessibility() { string source = @" using System.Runtime.CompilerServices; From 32d8526a21774cbaabbec05ddd57bb2ab320f32a Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 18:41:14 -0400 Subject: [PATCH 12/35] Group tests that vary only by keywords into theories --- .../ModuleInitializersTests.Accessibility.cs | 234 +++--------------- 1 file changed, 29 insertions(+), 205 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs index a56c452c355eb..61c456aeb26fe 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs @@ -8,8 +8,11 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols { public sealed partial class ModuleInitializersTests { - [Fact] - public void AccessibilityMustNotBePrivate() + [Theory] + [InlineData("private")] + [InlineData("protected")] + [InlineData("private protected")] + public void DisallowedMethodAccessibility(string keywords) { string source = @" using System.Runtime.CompilerServices; @@ -17,7 +20,7 @@ public void AccessibilityMustNotBePrivate() class C { [ModuleInitializer] - private static void M() { } + " + keywords + @" static void M() { } } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } @@ -30,70 +33,11 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } - [Fact] - public void AccessibilityMustNotBeProtected() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer] - protected static void M() { } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( - // (6,6): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' - // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) - ); - } - - [Fact] - public void AccessibilityMustNotBePrivateProtected() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer] - private protected static void M() { } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( - // (6,6): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' - // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) - ); - } - - [Fact] - public void AccessibilityMayBePublic() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer] - public static void M() { } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); - } - - [Fact] - public void AccessibilityMayBeInternal() + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected internal")] + public void AllowedMethodAccessibility(string keywords) { string source = @" using System.Runtime.CompilerServices; @@ -101,43 +45,7 @@ public void AccessibilityMayBeInternal() class C { [ModuleInitializer] - internal static void M() { } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); - } - - [Fact] - public void AccessibilityMayBeProtectedInternal() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer] - protected internal static void M() { } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); - } - - [Fact] - public void TopLevelTypeMayBeInternal() - { - string source = @" -using System.Runtime.CompilerServices; - -internal class C -{ - [ModuleInitializer] - public static void M() { } + " + keywords + @" static void M() { } } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } @@ -146,13 +54,15 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S compilation.VerifyDiagnostics(); } - [Fact] - public void TopLevelTypeMayBePublic() + [Theory] + [InlineData("public")] + [InlineData("internal")] + public void AllowedTopLevelTypeAccessibility(string keywords) { string source = @" using System.Runtime.CompilerServices; -public class C +" + keywords + @" class C { [ModuleInitializer] public static void M() { } @@ -164,65 +74,18 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S compilation.VerifyDiagnostics(); } - [Fact] - public void NestedTypeAccessibilityMustNotBePrivate() - { - string source = @" -using System.Runtime.CompilerServices; - -public class C -{ - private class Nested - { - [ModuleInitializer] - public static void M() { } - } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( - // (8,10): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' - // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) - ); - } - - [Fact] - public void NestedTypeAccessibilityMustNotBeProtected() - { - string source = @" -using System.Runtime.CompilerServices; - -public class C -{ - protected class Nested - { - [ModuleInitializer] - public static void M() { } - } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( - // (8,10): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' - // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) - ); - } - - [Fact] - public void NestedTypeAccessibilityMustNotBePrivateProtected() + [Theory] + [InlineData("private")] + [InlineData("protected")] + [InlineData("private protected")] + public void DisallowedNestedTypeAccessibility(string keywords) { string source = @" using System.Runtime.CompilerServices; public class C { - private protected class Nested + " + keywords + @" class Nested { [ModuleInitializer] public static void M() { } @@ -239,57 +102,18 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } - [Fact] - public void NestedTypeAccessibilityMayBePublic() - { - string source = @" -using System.Runtime.CompilerServices; - -public class C -{ - public class Nested - { - [ModuleInitializer] - public static void M() { } - } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); - } - - [Fact] - public void NestedTypeAccessibilityMayBeInternal() - { - string source = @" -using System.Runtime.CompilerServices; - -public class C -{ - internal class Nested - { - [ModuleInitializer] - public static void M() { } - } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); - } - - [Fact] - public void NestedTypeAccessibilityMayBeProtectedInternal() + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected internal")] + public void AllowedNestedTypeAccessibility(string keywords) { string source = @" using System.Runtime.CompilerServices; public class C { - protected internal class Nested + " + keywords + @" class Nested { [ModuleInitializer] public static void M() { } From c525661ce1711f24ec7d589d5c6caafe6043fe0e Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 19:42:11 -0400 Subject: [PATCH 13/35] Reserve the term 'ignored on' to indicate relying on AttributeUsage --- .../Symbols/ModuleInitializersTests.Targets.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs index c9d4f619a8564..f269dd2936c74 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols public sealed partial class ModuleInitializersTests { [Fact] - public void IgnoredOnLocalFunction() + public void TargetMustNotBeLocalFunction() { string source = @" using System.Runtime.CompilerServices; @@ -35,7 +35,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void IgnoredOnDestructor() + public void TargetMustNotBeDestructor() { string source = @" using System.Runtime.CompilerServices; @@ -57,7 +57,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void IgnoredOnOperator() + public void TargetMustNotBeOperator() { string source = @" using System.Runtime.CompilerServices; @@ -79,7 +79,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void IgnoredOnConversionOperator() + public void TargetMustNotBeConversionOperator() { string source = @" using System.Runtime.CompilerServices; @@ -101,7 +101,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void IgnoredOnEventAccessors() + public void TargetMustNotBeEventAccessor() { string source = @" using System.Runtime.CompilerServices; @@ -131,7 +131,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void IgnoredOnPropertyAccessors() + public void TargetMustNotBePropertyAccessor() { string source = @" using System.Runtime.CompilerServices; @@ -161,7 +161,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S } [Fact] - public void IgnoredOnIndexerAccessors() + public void TargetMustNotBeIndexerAccessor() { string source = @" using System.Runtime.CompilerServices; From dc2ad6b16fbd22f02b32c599c5864b38abaf9d65 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 18:41:52 -0400 Subject: [PATCH 14/35] Named arguments are not relevant --- .../ModuleInitializersTests.Ignored.cs | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs index bd382a8fccdcb..4bc80e97b7dba 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs @@ -258,32 +258,5 @@ public ModuleInitializerAttribute(int p) { } verifier.VerifyMemberInIL("..cctor", expected: false); } - - [Fact] - public void IgnoredWhenNamedArgumentIsSpecified() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer(P = 42)] - internal static void M() - { - } -} - -namespace System.Runtime.CompilerServices -{ - class ModuleInitializerAttribute : System.Attribute - { - public int P { get; set; } - } -} -"; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); - } } } From bdfce43316ccc246c4ad43a0cacc57fd7da6478d Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 19:23:18 -0400 Subject: [PATCH 15/35] type is no longer available to VerifyIL and VerifyMemberInIL --- .../ModuleInitializersTests.Ignored.cs | 105 +++++++++++------- .../Symbol/Symbols/ModuleInitializersTests.cs | 52 ++++----- 2 files changed, 86 insertions(+), 71 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs index 4bc80e97b7dba..45aae1247f016 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.CodeAnalysis.CSharp.Symbols; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols @@ -24,9 +25,11 @@ internal static void M() namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -44,9 +47,11 @@ internal static void M([ModuleInitializer] int p) namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -64,9 +69,11 @@ internal static void M<[ModuleInitializer] T>() namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -83,9 +90,11 @@ internal static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -102,9 +111,11 @@ static C() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -121,9 +132,11 @@ public C() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -140,9 +153,11 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -159,9 +174,11 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -178,9 +195,11 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -197,9 +216,11 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -212,9 +233,11 @@ public void IgnoredOnModule() namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -227,9 +250,11 @@ public void IgnoredOnAssembly() namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -254,9 +279,11 @@ public ModuleInitializerAttribute(int p) { } } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyMemberInIL("..cctor", expected: false); + CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => + { + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index d877ec70db19c..829a72025cce5 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -148,50 +148,46 @@ public void SingleCallIsGeneratedWhenMethodIsMarkedTwice() class C { [ModuleInitializer, ModuleInitializer] - internal static void M() { } + internal static void M() => Console.WriteLine(""C.M""); +} + +class Program +{ + static void Main() { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] - class ModuleInitializerAttribute : Attribute - { - } + class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyIL("..cctor", @" -{ - // Code size 6 (0x6) - .maxstack 0 - IL_0000: call ""void C.M()"" - IL_0005: ret -}"); + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: "C.M"); } [Fact] public void AttributeCanBeAppliedWithinItsOwnDefinition() { string source = @" +using System; + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); +} + namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { [ModuleInitializer] - internal static void M() { } + internal static void M() => Console.WriteLine(""ModuleInitializerAttribute.M""); } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyIL("..cctor", @" -{ - // Code size 6 (0x6) - .maxstack 0 - IL_0000: call ""void System.Runtime.CompilerServices.ModuleInitializerAttribute.M()"" - IL_0005: ret -}"); + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +ModuleInitializerAttribute.M +Program.Main"); } [Fact] @@ -209,15 +205,7 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var verifier = CompileAndVerify(source, parseOptions: s_parseOptions); - - verifier.VerifyIL("..cctor", @" -{ - // Code size 6 (0x6) - .maxstack 0 - IL_0000: call ""void C.M()"" - IL_0005: ret -}"); + CompileAndVerify(source, parseOptions: s_parseOptions); } } } From 03b0c497f45e7bb98f2b42e813c53fe0cd5e4145 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 19:39:58 -0400 Subject: [PATCH 16/35] Fix placeholder name --- .../CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index 829a72025cce5..6672941d2d7d4 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -199,7 +199,7 @@ public void ExternMethodCanBeModuleInitializer() class C { - [ModuleInitializer, DllImport(""foo"")] + [ModuleInitializer, DllImport(""dllName"")] internal static extern void M(); } From 3f310304275d668d3383103f27bf5bfc4959bd44 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 19:45:54 -0400 Subject: [PATCH 17/35] Emit diagnostics should be verified --- .../ModuleInitializersTests.Accessibility.cs | 18 +++++++++--------- .../ModuleInitializersTests.Generics.cs | 6 +++--- .../ModuleInitializersTests.Signature.cs | 14 +++++++------- .../Symbols/ModuleInitializersTests.Targets.cs | 14 +++++++------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs index 61c456aeb26fe..a899bbaf790e2 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs @@ -26,7 +26,7 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) @@ -51,7 +51,7 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); + compilation.VerifyEmitDiagnostics(); } [Theory] @@ -71,7 +71,7 @@ public static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); + compilation.VerifyEmitDiagnostics(); } [Theory] @@ -95,7 +95,7 @@ public static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (8,10): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) @@ -123,7 +123,7 @@ public static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); + compilation.VerifyEmitDiagnostics(); } [Fact] @@ -141,7 +141,7 @@ internal static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); + compilation.VerifyEmitDiagnostics(); } [Fact] @@ -160,7 +160,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (7,26): error CS8701: Target runtime doesn't support default interface implementation. // internal static void M() { } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M").WithLocation(7, 26) @@ -185,7 +185,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S // Intentionally demonstrated without DIM support. - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (7,17): error CS8701: Target runtime doesn't support default interface implementation. // static void M() { } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M").WithLocation(7, 17) @@ -210,7 +210,7 @@ internal static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics(); + compilation.VerifyEmitDiagnostics(); } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs index 9ae63b710e85b..f99b7b3fe1cc6 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs @@ -23,7 +23,7 @@ internal static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8798: Module initializer method 'M' must not have generic parameters // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeGeneric, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) @@ -45,7 +45,7 @@ internal static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8798: Module initializer method 'M' must not be contained in a generic type // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) @@ -70,7 +70,7 @@ internal static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (8,10): error CS8799: Module initializer method 'M' must not be contained in a generic type // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, "ModuleInitializer").WithArguments("M").WithLocation(8, 10) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs index 71913d276366f..21ea54e7c9819 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs @@ -23,7 +23,7 @@ internal void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8795: Module initializer method 'M' must be static // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStatic, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) @@ -45,7 +45,7 @@ internal static void M(object p) { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8796: Module initializer method 'M' must not have parameters // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) @@ -67,7 +67,7 @@ internal static void M(object p = null) { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8796: Module initializer method 'M' must not have parameters // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) @@ -89,7 +89,7 @@ internal static void M(params object[] p) { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8796: Module initializer method 'M' must not have parameters // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) @@ -111,7 +111,7 @@ static class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8797: Module initializer method 'M' must return void // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) @@ -133,7 +133,7 @@ internal static async void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (7,32): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. // internal static async void M() { } Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M").WithLocation(7, 32) @@ -156,7 +156,7 @@ internal static async Task M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (7,6): error CS8797: Module initializer method 'M' must return void // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, "ModuleInitializer").WithArguments("M").WithLocation(7, 6), diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs index f269dd2936c74..c54fdb545957a 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs @@ -27,7 +27,7 @@ static void LocalFunction() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (9,10): error CS8793: A module initializer must be an ordinary method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(9, 10) @@ -49,7 +49,7 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8793: A module initializer must be an ordinary method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) @@ -71,7 +71,7 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8793: A module initializer must be an ordinary method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) @@ -93,7 +93,7 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (6,6): error CS8793: A module initializer must be an ordinary method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) @@ -120,7 +120,7 @@ public event System.Action E namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (8,10): error CS8793: A module initializer must be an ordinary method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(8, 10), @@ -150,7 +150,7 @@ public int P namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (8,10): error CS8793: A module initializer must be an ordinary method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(8, 10), @@ -180,7 +180,7 @@ public int this[int p] namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyDiagnostics( + compilation.VerifyEmitDiagnostics( // (8,10): error CS8793: A module initializer must be an ordinary method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(8, 10), From 22af1ab87b3065f5f28eda6a0cb0d1213d7be0bb Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 20:13:24 -0400 Subject: [PATCH 18/35] Success cases should be executed --- .../ModuleInitializersTests.Accessibility.cs | 115 +++++++++++++----- .../ModuleInitializersTests.Signature.cs | 17 +-- 2 files changed, 92 insertions(+), 40 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs index a899bbaf790e2..703fa36a5a12d 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols @@ -40,18 +42,25 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S public void AllowedMethodAccessibility(string keywords) { string source = @" +using System; using System.Runtime.CompilerServices; class C { [ModuleInitializer] - " + keywords + @" static void M() { } + " + keywords + @" static void M() => Console.WriteLine(""C.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyEmitDiagnostics(); + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); } [Theory] @@ -60,18 +69,25 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S public void AllowedTopLevelTypeAccessibility(string keywords) { string source = @" +using System; using System.Runtime.CompilerServices; " + keywords + @" class C { [ModuleInitializer] - public static void M() { } + public static void M() => Console.WriteLine(""C.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyEmitDiagnostics(); + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); } [Theory] @@ -109,6 +125,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S public void AllowedNestedTypeAccessibility(string keywords) { string source = @" +using System; using System.Runtime.CompilerServices; public class C @@ -116,86 +133,112 @@ public class C " + keywords + @" class Nested { [ModuleInitializer] - public static void M() { } + public static void M() => Console.WriteLine(""C.M""); } } +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); +} + namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyEmitDiagnostics(); + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); } [Fact] public void MayBeDeclaredByStruct() { string source = @" +using System; using System.Runtime.CompilerServices; struct S { [ModuleInitializer] - internal static void M() { } + internal static void M() => Console.WriteLine(""C.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyEmitDiagnostics(); + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); } [Fact] public void MayBeDeclaredByInterface() { string source = @" +using System; using System.Runtime.CompilerServices; interface I { [ModuleInitializer] - internal static void M() { } + internal static void M() => Console.WriteLine(""I.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - - compilation.VerifyEmitDiagnostics( - // (7,26): error CS8701: Target runtime doesn't support default interface implementation. - // internal static void M() { } - Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M").WithLocation(7, 26) - ); + CompileAndVerify( + source, + parseOptions: s_parseOptions, + targetFramework: TargetFramework.NetStandardLatest, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @" +I.M +Program.Main" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped); } [Fact] public void ImplicitPublicInterfaceMethodAccessibility() { string source = @" +using System; using System.Runtime.CompilerServices; interface I { [ModuleInitializer] - static void M() { } + static void M() => Console.WriteLine(""I.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - - // Intentionally demonstrated without DIM support. - - compilation.VerifyEmitDiagnostics( - // (7,17): error CS8701: Target runtime doesn't support default interface implementation. - // static void M() { } - Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M").WithLocation(7, 17) - ); + CompileAndVerify( + source, + parseOptions: s_parseOptions, + targetFramework: TargetFramework.NetStandardLatest, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @" +I.M +Program.Main" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped); } [Fact] public void ImplicitPublicInterfaceNestedTypeAccessibility() { string source = @" +using System; using System.Runtime.CompilerServices; interface I @@ -203,14 +246,20 @@ interface I class Nested { [ModuleInitializer] - internal static void M() { } + internal static void M() => Console.WriteLine(""C.M""); } } +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); +} + namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyEmitDiagnostics(); + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs index 21ea54e7c9819..226334f5dc462 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs @@ -122,22 +122,25 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S public void MayBeAsyncVoid() { string source = @" +using System; using System.Runtime.CompilerServices; static class C { [ModuleInitializer] - internal static async void M() { } + internal static async void M() => Console.WriteLine(""C.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - var compilation = CreateCompilation(source, parseOptions: s_parseOptions); - compilation.VerifyEmitDiagnostics( - // (7,32): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. - // internal static async void M() { } - Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M").WithLocation(7, 32) - ); + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); } [Fact] From b140ab9f19a9d0f64a5ee09832c18c509f1b8a5d Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 20:37:47 -0400 Subject: [PATCH 19/35] Invalid methods should not be added as module initializers --- .../Source/SourceMethodSymbolWithAttributes.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 4e21bce9272ba..916a1f829cbcf 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -780,39 +780,49 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< } Debug.Assert(ContainingType is object); + var hasError = false; if (isInaccessible(this) || containingTypes(this).Any(isInaccessible)) { var topLevelType = containingTypes(this).Last(); arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, arguments.AttributeSyntaxOpt.Location, Name, topLevelType.Name); + hasError = true; } if (!IsStatic) { arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeStatic, arguments.AttributeSyntaxOpt.Location, Name); + hasError = true; } if (ParameterCount > 0) { arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, arguments.AttributeSyntaxOpt.Location, Name); + hasError = true; } if (!ReturnsVoid) { arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, arguments.AttributeSyntaxOpt.Location, Name); + hasError = true; } if (IsGenericMethod) { arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustNotBeGeneric, arguments.AttributeSyntaxOpt.Location, Name); + hasError = true; } if (ContainingType.IsGenericType) { arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, arguments.AttributeSyntaxOpt.Location, Name); + hasError = true; } - DeclaringCompilation.AddModuleInitializerMethod(this); + if (!hasError) + { + DeclaringCompilation.AddModuleInitializerMethod(this); + } static bool isInaccessible(Symbol symbol) { From 3328ade9ac311024c0c00de0f29f93a85dc48866 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Thu, 30 Apr 2020 20:49:05 -0400 Subject: [PATCH 20/35] Use existing helper to check accessibility --- .../Source/SourceMethodSymbolWithAttributes.cs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 916a1f829cbcf..3c0b265a0d874 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -782,7 +782,8 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< Debug.Assert(ContainingType is object); var hasError = false; - if (isInaccessible(this) || containingTypes(this).Any(isInaccessible)) + HashSet? useSiteDiagnostics = null; + if (!AccessCheck.IsSymbolAccessible(this, ContainingAssembly, ref useSiteDiagnostics)) { var topLevelType = containingTypes(this).Last(); arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, arguments.AttributeSyntaxOpt.Location, Name, topLevelType.Name); @@ -824,19 +825,6 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< DeclaringCompilation.AddModuleInitializerMethod(this); } - static bool isInaccessible(Symbol symbol) - { - switch (symbol.DeclaredAccessibility) - { - case Accessibility.Private: - case Accessibility.Protected: - case Accessibility.ProtectedAndInternal: - return true; - default: - return false; - } - } - static IEnumerable containingTypes(Symbol symbol) { for (var type = symbol.ContainingType; type is { }; type = type.ContainingType) From fc412ac592895c4a44417687a632cd9b7f1a1776 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Fri, 1 May 2020 20:38:02 -0400 Subject: [PATCH 21/35] Draw the line between ignored and error placements as defined by the SourceMethod boundary rather than AttributeTargets.Method --- .../SourceMethodSymbolWithAttributes.cs | 7 +-- .../ModuleInitializersTests.Ignored.cs | 42 ------------------ .../ModuleInitializersTests.Targets.cs | 44 +++++++++++++++++++ 3 files changed, 45 insertions(+), 48 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 3c0b265a0d874..d0a82fc877832 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -770,12 +770,7 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< if (MethodKind != MethodKind.Ordinary) { - // Ignore cases where there will already be a warning due to the AttributeTargets.Method usage - // restriction on the attribute definition in the framework. - if (MethodKind != MethodKind.Constructor && MethodKind != MethodKind.StaticConstructor) - { - arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, arguments.AttributeSyntaxOpt.Location); - } + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, arguments.AttributeSyntaxOpt.Location); return; } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs index 45aae1247f016..a1f44775bf9de 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs @@ -88,48 +88,6 @@ class C internal static void M() { } } -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); - } - - [Fact] - public void IgnoredOnStaticConstructor() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer] - static C() { } -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); - } - - [Fact] - public void IgnoredOnInstanceConstructor() - { - string source = @" -using System.Runtime.CompilerServices; - -class C -{ - [ModuleInitializer] - public C() { } -} - namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs index c54fdb545957a..b10b757239856 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs @@ -189,5 +189,49 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(10, 10) ); } + + [Fact] + public void TargetMustNotBeStaticConstructor() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + static C() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (6,6): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) + ); + } + + [Fact] + public void TargetMustNotBeInstanceConstructor() + { + string source = @" +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public C() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (6,6): error CS8793: A module initializer must be an ordinary method + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) + ); + } } } From 8f576b5343bb26f72758d0e9c1555bf8eafe2d1a Mon Sep 17 00:00:00 2001 From: jnm2 Date: Fri, 1 May 2020 22:07:09 -0400 Subject: [PATCH 22/35] Mirror tests requested for mismatching AttributeTargets --- .../ModuleInitializersTests.Targets.cs | 271 ++++++++++++++++++ 1 file changed, 271 insertions(+) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs index b10b757239856..b6b10ea896d92 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs @@ -34,6 +34,37 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } + [Fact] + public void IgnoredOnLocalFunctionWithBadAttributeTargets() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + internal static void M() + { + LocalFunction(); + [ModuleInitializer] + static void LocalFunction() { } + } +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class)] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (10,10): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(10, 10) + ); + } + [Fact] public void TargetMustNotBeDestructor() { @@ -56,6 +87,33 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } + [Fact] + public void IgnoredOnDestructorWithBadAttributeTargets() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + ~C() { } +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class)] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (7,6): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(7, 6) + ); + } + [Fact] public void TargetMustNotBeOperator() { @@ -78,6 +136,33 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } + [Fact] + public void IgnoredOnOperatorWithBadAttributeTargets() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public static C operator -(C p) => p; +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class)] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (7,6): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(7, 6) + ); + } + [Fact] public void TargetMustNotBeConversionOperator() { @@ -100,6 +185,33 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } + [Fact] + public void IgnoredOnConversionOperatorWithBadAttributeTargets() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public static explicit operator int(C p) => default; +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class)] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (7,6): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(7, 6) + ); + } + [Fact] public void TargetMustNotBeEventAccessor() { @@ -130,6 +242,41 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } + [Fact] + public void IgnoredOnEventAccessorsWithBadAttributeTargets() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + public event System.Action E + { + [ModuleInitializer] + add { } + [ModuleInitializer] + remove { } + } +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class)] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (9,10): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(9, 10), + // (11,10): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(11, 10) + ); + } + [Fact] public void TargetMustNotBePropertyAccessor() { @@ -160,6 +307,41 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } + [Fact] + public void IgnoredOnPropertyAccessorsWithBadAttributeTargets() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + public int P + { + [ModuleInitializer] + get; + [ModuleInitializer] + set; + } +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class)] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (9,10): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(9, 10), + // (11,10): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(11, 10) + ); + } + [Fact] public void TargetMustNotBeIndexerAccessor() { @@ -190,6 +372,41 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } + [Fact] + public void IgnoredOnIndexerAccessorsWithBadAttributeTargets() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + public int this[int p] + { + [ModuleInitializer] + get => p; + [ModuleInitializer] + set { } + } +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class)] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (9,10): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(9, 10), + // (11,10): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(11, 10) + ); + } + [Fact] public void TargetMustNotBeStaticConstructor() { @@ -212,6 +429,33 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S ); } + [Fact] + public void IgnoredOnStaticConstructorWithBadAttributeTargets() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + static C() { } +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class)] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (7,6): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(7, 6) + ); + } + [Fact] public void TargetMustNotBeInstanceConstructor() { @@ -233,5 +477,32 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) ); } + + [Fact] + public void IgnoredOnInstanceConstructorWithBadAttributeTargets() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + public C() { } +} + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class)] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + var compilation = CreateCompilation(source, parseOptions: s_parseOptions); + compilation.VerifyEmitDiagnostics( + // (7,6): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // [ModuleInitializer] + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(7, 6) + ); + } } } From 6663f90fa9ff092cd7bc68b6014e5c63cce57e54 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sat, 2 May 2020 12:00:08 -0400 Subject: [PATCH 23/35] Report additional diagnostics from accessibility check as requested --- .../Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index d0a82fc877832..1384a4e9e5b88 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -785,6 +785,8 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< hasError = true; } + arguments.Diagnostics.Add(arguments.AttributeSyntaxOpt, useSiteDiagnostics); + if (!IsStatic) { arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeStatic, arguments.AttributeSyntaxOpt.Location, Name); From fb488e04073f61e4494460d738cfce1075331fc4 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sat, 2 May 2020 12:46:49 -0400 Subject: [PATCH 24/35] Unify error messages as suggested in review, referencing WRN_MainCantBeGeneric and MissingDeconstruct and quoting 'void' as inline syntax rather than as language terminology --- .../CSharp/Portable/CSharpResources.resx | 19 +++------- .../CSharp/Portable/Errors/ErrorCode.cs | 7 ++-- .../SourceMethodSymbolWithAttributes.cs | 26 +++----------- .../Portable/xlf/CSharpResources.cs.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.de.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.es.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.fr.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.it.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.ja.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.ko.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.pl.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.pt-BR.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.ru.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.tr.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.zh-Hans.xlf | 35 ++++++------------- .../Portable/xlf/CSharpResources.zh-Hant.xlf | 35 ++++++------------- .../ModuleInitializersTests.Generics.cs | 12 +++---- .../ModuleInitializersTests.Signature.cs | 24 ++++++------- 18 files changed, 159 insertions(+), 384 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 46dd147185689..e9403724a5547 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -6076,22 +6076,13 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Module initializer method '{0}' must be accessible outside top-level type '{1}' - - Module initializer method '{0}' must be static + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' - - Module initializer method '{0}' must not be contained in a generic type - - - Module initializer method '{0}' must not have generic parameters - - - Module initializer method '{0}' must not have parameters - - - Module initializer method '{0}' must return void + + Module initializer method '{0}' must not be generic and must not be contained in a generic type - A module initializer must be an ordinary method + A module initializer must be an ordinary member method \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 19d0e8e343f13..927bc54753e64 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1779,11 +1779,8 @@ internal enum ErrorCode ERR_ModuleInitializerMethodMustBeOrdinary = 8793, ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType = 8794, - ERR_ModuleInitializerMethodMustBeStatic = 8795, - ERR_ModuleInitializerMethodMustNotHaveParameters = 8796, - ERR_ModuleInitializerMethodMustReturnVoid = 8797, - ERR_ModuleInitializerMethodMustNotBeGeneric = 8798, - ERR_ModuleInitializerMethodMustNotBeContainedInGenericType = 8799, + ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid = 8795, + ERR_ModuleInitializerMethodAndContainingTypesMustNotBeGeneric = 8796, // Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd) } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 1384a4e9e5b88..5dd0697b50e38 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -787,33 +787,15 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< arguments.Diagnostics.Add(arguments.AttributeSyntaxOpt, useSiteDiagnostics); - if (!IsStatic) + if (!IsStatic || ParameterCount > 0 || !ReturnsVoid) { - arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeStatic, arguments.AttributeSyntaxOpt.Location, Name); + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid, arguments.AttributeSyntaxOpt.Location, Name); hasError = true; } - if (ParameterCount > 0) + if (IsGenericMethod || ContainingType.IsGenericType) { - arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, arguments.AttributeSyntaxOpt.Location, Name); - hasError = true; - } - - if (!ReturnsVoid) - { - arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, arguments.AttributeSyntaxOpt.Location, Name); - hasError = true; - } - - if (IsGenericMethod) - { - arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustNotBeGeneric, arguments.AttributeSyntaxOpt.Location, Name); - hasError = true; - } - - if (ContainingType.IsGenericType) - { - arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, arguments.AttributeSyntaxOpt.Location, Name); + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodAndContainingTypesMustNotBeGeneric, arguments.AttributeSyntaxOpt.Location, Name); hasError = true; } diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 41d62413778e3..c0432c10a6901 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -327,39 +327,24 @@ Chybějící vzor + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 26fe59f368cd4..8d69b510c39e0 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -327,39 +327,24 @@ Muster fehlt. + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 7e77b08dbef5a..866a9c2c48938 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -327,39 +327,24 @@ Falta un patrón. + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 7415b8d5c93a2..ef43a0ae95ded 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -327,39 +327,24 @@ Modèle manquant + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 84b2b31c43916..f1d9b3c0e015d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -327,39 +327,24 @@ Criterio mancante + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index ada6a7f816cf0..2eb0d1d7cda0e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -327,39 +327,24 @@ パターンがありません + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 11f0bf2c953ac..a77167770cd52 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -327,39 +327,24 @@ 패턴이 없습니다. + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index afbe60e014ac1..67104c5c7a65b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -327,39 +327,24 @@ Brak wzorca + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 8820d3a259e29..b67ea7d27634d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -327,39 +327,24 @@ Padrão ausente + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index ee071dd5fc2c5..334e2cea7222e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -327,39 +327,24 @@ Отсутствует шаблон + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 3cb970c35ea91..503dcc96eaab4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -327,39 +327,24 @@ Desen eksik + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 8cd2d4c2992f1..846bfa91209f8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -327,39 +327,24 @@ 模式缺失 + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index d762f8d0b0f85..58746bf26999c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -327,39 +327,24 @@ 缺少模式 + + Module initializer method '{0}' must not be generic and must not be contained in a generic type + Module initializer method '{0}' must not be generic and must not be contained in a generic type + + Module initializer method '{0}' must be accessible outside top-level type '{1}' Module initializer method '{0}' must be accessible outside top-level type '{1}' - A module initializer must be an ordinary method - A module initializer must be an ordinary method - - - - Module initializer method '{0}' must be static - Module initializer method '{0}' must be static - - - - Module initializer method '{0}' must not be contained in a generic type - Module initializer method '{0}' must not be contained in a generic type - - - - Module initializer method '{0}' must not have generic parameters - Module initializer method '{0}' must not have generic parameters - - - - Module initializer method '{0}' must not have parameters - Module initializer method '{0}' must not have parameters + A module initializer must be an ordinary member method + A module initializer must be an ordinary member method - - Module initializer method '{0}' must return void - Module initializer method '{0}' must return void + + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' + Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs index f99b7b3fe1cc6..4eadb94b75a18 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs @@ -24,9 +24,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8798: Module initializer method 'M' must not have generic parameters + // (6,6): error CS8796: Module initializer method 'M' must not be generic and must not be contained in a generic type // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeGeneric, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodAndContainingTypesMustNotBeGeneric, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); } @@ -46,9 +46,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8798: Module initializer method 'M' must not be contained in a generic type + // (6,6): error CS8796: Module initializer method 'M' must not be generic and must not be contained in a generic type // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodAndContainingTypesMustNotBeGeneric, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); } @@ -71,9 +71,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (8,10): error CS8799: Module initializer method 'M' must not be contained in a generic type + // (8,10): error CS8796: Module initializer method 'M' must not be generic and must not be contained in a generic type // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotBeContainedInGenericType, "ModuleInitializer").WithArguments("M").WithLocation(8, 10) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodAndContainingTypesMustNotBeGeneric, "ModuleInitializer").WithArguments("M").WithLocation(8, 10) ); } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs index 226334f5dc462..b71360e39dbc7 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs @@ -24,9 +24,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8795: Module initializer method 'M' must be static + // (6,6): error CS8795: must be static, must have no parameters, and must return 'void' // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStatic, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); } @@ -46,9 +46,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8796: Module initializer method 'M' must not have parameters + // (6,6): error CS8795: must be static, must have no parameters, and must return 'void' // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); } @@ -68,9 +68,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8796: Module initializer method 'M' must not have parameters + // (6,6): error CS8795: must be static, must have no parameters, and must return 'void' // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); } @@ -90,9 +90,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8796: Module initializer method 'M' must not have parameters + // (6,6): error CS8795: must be static, must have no parameters, and must return 'void' // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustNotHaveParameters, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); } @@ -112,9 +112,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8797: Module initializer method 'M' must return void + // (6,6): error CS8795: must be static, must have no parameters, and must return 'void' // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); } @@ -160,9 +160,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (7,6): error CS8797: Module initializer method 'M' must return void + // (7,6): error CS8795: must be static, must have no parameters, and must return 'void' // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustReturnVoid, "ModuleInitializer").WithArguments("M").WithLocation(7, 6), + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid, "ModuleInitializer").WithArguments("M").WithLocation(7, 6), // (8,32): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. // internal static async Task M() { } Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "M").WithLocation(8, 32)); From c36b1676350b67d1467ae6e6efcd30bec4334f12 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Tue, 5 May 2020 23:13:07 -0400 Subject: [PATCH 25/35] Update code comments to be consistent with .resx change --- .../ModuleInitializersTests.Targets.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs index b6b10ea896d92..f21adcd27810b 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs @@ -28,7 +28,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (9,10): error CS8793: A module initializer must be an ordinary method + // (9,10): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(9, 10) ); @@ -81,7 +81,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8793: A module initializer must be an ordinary method + // (6,6): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) ); @@ -130,7 +130,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8793: A module initializer must be an ordinary method + // (6,6): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) ); @@ -179,7 +179,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8793: A module initializer must be an ordinary method + // (6,6): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) ); @@ -233,10 +233,10 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (8,10): error CS8793: A module initializer must be an ordinary method + // (8,10): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(8, 10), - // (10,10): error CS8793: A module initializer must be an ordinary method + // (10,10): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(10, 10) ); @@ -298,10 +298,10 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (8,10): error CS8793: A module initializer must be an ordinary method + // (8,10): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(8, 10), - // (10,10): error CS8793: A module initializer must be an ordinary method + // (10,10): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(10, 10) ); @@ -363,10 +363,10 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (8,10): error CS8793: A module initializer must be an ordinary method + // (8,10): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(8, 10), - // (10,10): error CS8793: A module initializer must be an ordinary method + // (10,10): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(10, 10) ); @@ -423,7 +423,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8793: A module initializer must be an ordinary method + // (6,6): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) ); @@ -472,7 +472,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8793: A module initializer must be an ordinary method + // (6,6): error CS8793: A module initializer must be an ordinary member method // [ModuleInitializer] Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary, "ModuleInitializer").WithLocation(6, 6) ); From cb70fe4c03349d0a5b3133b47d38e2ec9aca462b Mon Sep 17 00:00:00 2001 From: jnm2 Date: Tue, 5 May 2020 23:04:18 -0400 Subject: [PATCH 26/35] Clearer message for inaccessible module initializer methods --- src/Compilers/CSharp/Portable/CSharpResources.resx | 2 +- .../Source/SourceMethodSymbolWithAttributes.cs | 11 +---------- .../CSharp/Portable/xlf/CSharpResources.cs.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.de.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.es.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.fr.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.it.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.ja.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.ko.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.pl.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.pt-BR.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.ru.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.tr.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf | 4 ++-- .../CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf | 4 ++-- .../Symbols/ModuleInitializersTests.Accessibility.cs | 8 ++++---- 16 files changed, 32 insertions(+), 41 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index e9403724a5547..78ce9c94748c6 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -6074,7 +6074,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ module initializers - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level Module initializer method '{0}' must be static, must have no parameters, and must return 'void' diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 5dd0697b50e38..5b6f660068fd5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -780,8 +780,7 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< HashSet? useSiteDiagnostics = null; if (!AccessCheck.IsSymbolAccessible(this, ContainingAssembly, ref useSiteDiagnostics)) { - var topLevelType = containingTypes(this).Last(); - arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, arguments.AttributeSyntaxOpt.Location, Name, topLevelType.Name); + arguments.Diagnostics.Add(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, arguments.AttributeSyntaxOpt.Location, Name); hasError = true; } @@ -803,14 +802,6 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< { DeclaringCompilation.AddModuleInitializerMethod(this); } - - static IEnumerable containingTypes(Symbol symbol) - { - for (var type = symbol.ContainingType; type is { }; type = type.ContainingType) - { - yield return type; - } - } } #nullable restore diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index c0432c10a6901..35507341097e8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 8d69b510c39e0..d6a795459fa06 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 866a9c2c48938..4134821a2e06f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index ef43a0ae95ded..063d4f00dcec6 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index f1d9b3c0e015d..9adafc8761c02 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 2eb0d1d7cda0e..864fad704d846 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index a77167770cd52..b081666b47d55 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 67104c5c7a65b..5969c091f0d3c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index b67ea7d27634d..fb06d4cf623c6 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 334e2cea7222e..62822861435a7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 503dcc96eaab4..db1ca717798a9 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 846bfa91209f8..89bbcf364f90f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 58746bf26999c..7e90b12af7975 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -333,8 +333,8 @@ - Module initializer method '{0}' must be accessible outside top-level type '{1}' - Module initializer method '{0}' must be accessible outside top-level type '{1}' + Module initializer method '{0}' must be accessible at the module level + Module initializer method '{0}' must be accessible at the module level diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs index 703fa36a5a12d..15df8ae53e7d6 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs @@ -29,9 +29,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (6,6): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' + // (6,6): error CS8794: Module initializer method 'M' must be accessible at the module level // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(6, 6) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M").WithLocation(6, 6) ); } @@ -112,9 +112,9 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (8,10): error CS8794: Module initializer method 'M' must be accessible outside top-level type 'C' + // (8,10): error CS8794: Module initializer method 'M' must be accessible at the module level // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M", "C").WithLocation(8, 10) + Diagnostic(ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType, "ModuleInitializer").WithArguments("M").WithLocation(8, 10) ); } From 8212adc2b5117280f0060c5431bc2e1c6763ac2e Mon Sep 17 00:00:00 2001 From: jnm2 Date: Tue, 5 May 2020 23:26:24 -0400 Subject: [PATCH 27/35] Prevent false negatives when expecting a missing module initializer --- .../ModuleInitializersTests.Ignored.cs | 156 ++++++++++++------ .../Symbol/Symbols/ModuleInitializersTests.cs | 4 +- 2 files changed, 104 insertions(+), 56 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs index a1f44775bf9de..bf003dffb5838 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs @@ -3,6 +3,8 @@ // See the LICENSE file in the project root for more information. using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols @@ -25,11 +27,15 @@ internal static void M() namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -47,11 +53,15 @@ internal static void M([ModuleInitializer] int p) namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -69,11 +79,15 @@ internal static void M<[ModuleInitializer] T>() namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -90,11 +104,15 @@ internal static void M() { } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -111,11 +129,15 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -132,11 +154,15 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -153,11 +179,15 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -174,11 +204,15 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -191,11 +225,15 @@ public void IgnoredOnModule() namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -208,11 +246,15 @@ public void IgnoredOnAssembly() namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } [Fact] @@ -237,11 +279,15 @@ public ModuleInitializerAttribute(int p) { } } } "; - CompileAndVerify(source, parseOptions: s_parseOptions, symbolValidator: module => - { - var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); - Assert.Null(rootModuleType.GetMember(".cctor")); - }); + CompileAndVerify( + source, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index 6672941d2d7d4..656e04d6af3c2 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -81,9 +81,10 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S CompileAndVerify( source, parseOptions: s_parseOptions, - options: new CSharpCompilationOptions(OutputKind.ConsoleApplication, metadataImportOptions: MetadataImportOptions.All), + options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), symbolValidator: module => { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); Assert.Null(rootModuleType.GetMember(".cctor")); }, @@ -118,6 +119,7 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), symbolValidator: module => { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); var rootModuleType = (TypeSymbol)module.GlobalNamespace.GetMember(""); var staticConstructor = (PEMethodSymbol)rootModuleType.GetMember(".cctor"); From 81b4d332243b724c8b4b30883580deeadcf9e80c Mon Sep 17 00:00:00 2001 From: jnm2 Date: Tue, 5 May 2020 23:31:15 -0400 Subject: [PATCH 28/35] Make ignored constructor attribute tests more interesting --- .../Symbols/ModuleInitializersTests.Targets.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs index f21adcd27810b..47c0e7703d9d3 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs @@ -444,15 +444,15 @@ static C() { } namespace System.Runtime.CompilerServices { - [AttributeUsage(AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Method)] class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (7,6): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // (7,6): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'method' declarations. // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(7, 6) + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "method").WithLocation(7, 6) ); } @@ -493,15 +493,15 @@ public C() { } namespace System.Runtime.CompilerServices { - [AttributeUsage(AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Method)] class ModuleInitializerAttribute : System.Attribute { } } "; var compilation = CreateCompilation(source, parseOptions: s_parseOptions); compilation.VerifyEmitDiagnostics( - // (7,6): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'class' declarations. + // (7,6): error CS0592: Attribute 'ModuleInitializer' is not valid on this declaration type. It is only valid on 'method' declarations. // [ModuleInitializer] - Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "class").WithLocation(7, 6) + Diagnostic(ErrorCode.ERR_AttributeOnBadSymbolType, "ModuleInitializer").WithArguments("ModuleInitializer", "method").WithLocation(7, 6) ); } } From dc03fbec51304bf729d46205774a6ef844646d3f Mon Sep 17 00:00:00 2001 From: jnm2 Date: Wed, 6 May 2020 17:53:33 -0400 Subject: [PATCH 29/35] Not accessibility tests --- .../ModuleInitializersTests.Accessibility.cs | 55 ------------------ .../Symbol/Symbols/ModuleInitializersTests.cs | 56 +++++++++++++++++++ 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs index c8027a68a5f80..e977f59c0c02e 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs @@ -149,61 +149,6 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S Program.Main"); } - [Fact] - public void MayBeDeclaredByStruct() - { - string source = @" -using System; -using System.Runtime.CompilerServices; - -struct S -{ - [ModuleInitializer] - internal static void M() => Console.WriteLine(""C.M""); -} - -class Program -{ - static void Main() => Console.WriteLine(""Program.Main""); -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" -C.M -Program.Main"); - } - - [Fact] - public void MayBeDeclaredByInterface() - { - string source = @" -using System; -using System.Runtime.CompilerServices; - -interface I -{ - [ModuleInitializer] - internal static void M() => Console.WriteLine(""I.M""); -} - -class Program -{ - static void Main() => Console.WriteLine(""Program.Main""); -} - -namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } -"; - CompileAndVerify( - source, - parseOptions: s_parseOptions, - targetFramework: TargetFramework.NetStandardLatest, - expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @" -I.M -Program.Main" : null, - verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped); - } - [Fact] public void ImplicitPublicInterfaceMethodAccessibility() { diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index 656e04d6af3c2..ec6824d0fba7e 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols @@ -209,5 +210,60 @@ namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : S "; CompileAndVerify(source, parseOptions: s_parseOptions); } + + [Fact] + public void MayBeDeclaredByStruct() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +struct S +{ + [ModuleInitializer] + internal static void M() => Console.WriteLine(""C.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); + } + + [Fact] + public void MayBeDeclaredByInterface() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +interface I +{ + [ModuleInitializer] + internal static void M() => Console.WriteLine(""I.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + CompileAndVerify( + source, + parseOptions: s_parseOptions, + targetFramework: TargetFramework.NetStandardLatest, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @" +I.M +Program.Main" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped); + } } } From f3adf4e060cc7a8b53493435f027686f62afe28d Mon Sep 17 00:00:00 2001 From: jnm2 Date: Fri, 8 May 2020 18:08:27 -0400 Subject: [PATCH 30/35] Write the correct member name --- .../CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index 10ca30c032761..ec8bb75c8b5e6 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -221,7 +221,7 @@ public void MayBeDeclaredByStruct() struct S { [ModuleInitializer] - internal static void M() => Console.WriteLine(""C.M""); + internal static void M() => Console.WriteLine(""S.M""); } class Program @@ -232,7 +232,7 @@ class Program namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" -C.M +S.M Program.Main"); } From afcb7011dfbc024fca0b9e24d2171e1d174cca96 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Fri, 8 May 2020 18:34:39 -0400 Subject: [PATCH 31/35] Add tests of conditional method and attribute --- .../Symbol/Symbols/ModuleInitializersTests.cs | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index ec8bb75c8b5e6..3e2ebc90ee6e8 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -648,5 +648,119 @@ void validator(ModuleSymbol module) Assert.NotNull(moduleType.GetMember(".cctor")); } } + + [Fact] + public void ModuleInitializerAttributeIncludedByConditionalAttribute() + { + string source = @" +#define INCLUDE + +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + internal static void M() => Console.WriteLine(""C.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); +} + +namespace System.Runtime.CompilerServices +{ + [System.Diagnostics.Conditional(""INCLUDE"")] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); + } + + [Fact] + public void ModuleInitializerAttributeExcludedByConditionalAttribute() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer] + internal static void M() => Console.WriteLine(""C.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); +} + +namespace System.Runtime.CompilerServices +{ + [System.Diagnostics.Conditional(""EXCLUDE"")] + class ModuleInitializerAttribute : System.Attribute { } +} +"; + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); + } + + [Fact] + public void ModuleInitializerMethodIncludedByConditionalAttribute() + { + string source = @" +#define INCLUDE + +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer, System.Diagnostics.Conditional(""INCLUDE"")] + internal static void M() => Console.WriteLine(""C.M""); +} + +class Program +{ + static void Main() => Console.WriteLine(""Program.Main""); +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" +C.M +Program.Main"); + } + + [Fact] + public void ModuleInitializerMethodExcludedByConditionalAttribute() + { + string source = @" +using System; +using System.Runtime.CompilerServices; + +class C +{ + [ModuleInitializer, System.Diagnostics.Conditional(""EXCLUDE"")] + internal static void M() { } +} + +namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } +"; + CompileAndVerify( + source, + parseOptions: s_parseOptions, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = module.ContainingAssembly.GetTypeByMetadataName(""); + Assert.Null(rootModuleType.GetMember(".cctor")); + }); + } } } From 5d9c8d8207c2a1c84078edcf1df7d52e0ac652e9 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Fri, 8 May 2020 18:41:48 -0400 Subject: [PATCH 32/35] Do not emit call to method that is conditionally excluded --- .../Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 5b6f660068fd5..1eb7ff5106e1f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -798,7 +798,7 @@ private void DecodeModuleInitializerAttribute(DecodeWellKnownAttributeArguments< hasError = true; } - if (!hasError) + if (!hasError && !CallsAreOmitted(arguments.AttributeSyntaxOpt.SyntaxTree)) { DeclaringCompilation.AddModuleInitializerMethod(this); } From 64269a91b40f475721946f230ad465971a6e87b9 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Fri, 8 May 2020 18:45:22 -0400 Subject: [PATCH 33/35] Verify that a module initializer is emitted for an extern method --- .../Test/Symbol/Symbols/ModuleInitializersTests.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs index 3e2ebc90ee6e8..33a3f31028dd5 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs @@ -208,7 +208,16 @@ class C namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; - CompileAndVerify(source, parseOptions: s_parseOptions); + CompileAndVerify( + source, + parseOptions: s_parseOptions, + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), + symbolValidator: module => + { + Assert.Equal(MetadataImportOptions.All, ((PEModuleSymbol)module).ImportOptions); + var rootModuleType = module.ContainingAssembly.GetTypeByMetadataName(""); + Assert.NotNull(rootModuleType.GetMember(".cctor")); + }); } [Fact] From e11ff633c60663b6c936a9f404c35120f11837cd Mon Sep 17 00:00:00 2001 From: jnm2 Date: Sat, 9 May 2020 14:36:06 -0400 Subject: [PATCH 34/35] Use subfolder instead of partial classes --- .../AccessibilityTests.cs} | 8 ++++++-- .../GenericsTests.cs} | 9 +++++++-- .../IgnoredTests.cs} | 6 ++++-- .../{ => ModuleInitializers}/ModuleInitializersTests.cs | 4 ++-- .../SignatureTests.cs} | 9 +++++++-- .../TargetsTests.cs} | 9 +++++++-- 6 files changed, 33 insertions(+), 12 deletions(-) rename src/Compilers/CSharp/Test/Symbol/Symbols/{ModuleInitializersTests.Accessibility.cs => ModuleInitializers/AccessibilityTests.cs} (94%) rename src/Compilers/CSharp/Test/Symbol/Symbols/{ModuleInitializersTests.Generics.cs => ModuleInitializers/GenericsTests.cs} (88%) rename src/Compilers/CSharp/Test/Symbol/Symbols/{ModuleInitializersTests.Ignored.cs => ModuleInitializers/IgnoredTests.cs} (97%) rename src/Compilers/CSharp/Test/Symbol/Symbols/{ => ModuleInitializers}/ModuleInitializersTests.cs (99%) rename src/Compilers/CSharp/Test/Symbol/Symbols/{ModuleInitializersTests.Signature.cs => ModuleInitializers/SignatureTests.cs} (94%) rename src/Compilers/CSharp/Test/Symbol/Symbols/{ModuleInitializersTests.Targets.cs => ModuleInitializers/TargetsTests.cs} (97%) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/AccessibilityTests.cs similarity index 94% rename from src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs rename to src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/AccessibilityTests.cs index e977f59c0c02e..10e75f994b21d 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Accessibility.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/AccessibilityTests.cs @@ -2,14 +2,18 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.ModuleInitializers { - public sealed partial class ModuleInitializersTests + [CompilerTrait(CompilerFeature.ModuleInitializers)] + public sealed class AccessibilityTests : CSharpTestBase { + private static readonly CSharpParseOptions s_parseOptions = TestOptions.RegularPreview; + [Theory] [InlineData("private")] [InlineData("protected")] diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/GenericsTests.cs similarity index 88% rename from src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs rename to src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/GenericsTests.cs index 33042acc9b002..0e607580838cc 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Generics.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/GenericsTests.cs @@ -2,12 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.ModuleInitializers { - public sealed partial class ModuleInitializersTests + [CompilerTrait(CompilerFeature.ModuleInitializers)] + public sealed class GenericsTests : CSharpTestBase { + private static readonly CSharpParseOptions s_parseOptions = TestOptions.RegularPreview; + [Fact] public void MustNotBeGenericMethod() { diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/IgnoredTests.cs similarity index 97% rename from src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs rename to src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/IgnoredTests.cs index bf003dffb5838..a2b6c65e5438e 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Ignored.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/IgnoredTests.cs @@ -5,11 +5,13 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.ModuleInitializers { - public sealed partial class ModuleInitializersTests + [CompilerTrait(CompilerFeature.ModuleInitializers)] + public sealed class IgnoredTests : CSharpTestBase { [Fact] public void IgnoredOnReturnValue() diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/ModuleInitializersTests.cs similarity index 99% rename from src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs rename to src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/ModuleInitializersTests.cs index 33a3f31028dd5..c0e2bebb3f878 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/ModuleInitializersTests.cs @@ -10,10 +10,10 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.ModuleInitializers { [CompilerTrait(CompilerFeature.ModuleInitializers)] - public sealed partial class ModuleInitializersTests : CSharpTestBase + public sealed class ModuleInitializersTests : CSharpTestBase { private static readonly CSharpParseOptions s_parseOptions = TestOptions.RegularPreview; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/SignatureTests.cs similarity index 94% rename from src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs rename to src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/SignatureTests.cs index b430af5e3372d..55e9e253f4a10 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Signature.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/SignatureTests.cs @@ -2,12 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.ModuleInitializers { - public sealed partial class ModuleInitializersTests + [CompilerTrait(CompilerFeature.ModuleInitializers)] + public sealed class SignatureTests : CSharpTestBase { + private static readonly CSharpParseOptions s_parseOptions = TestOptions.RegularPreview; + [Fact] public void MustNotBeInstanceMethod() { diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/TargetsTests.cs similarity index 97% rename from src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs rename to src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/TargetsTests.cs index 5e5ccad22fe76..41ac4acc4880e 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializersTests.Targets.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/TargetsTests.cs @@ -2,12 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.ModuleInitializers { - public sealed partial class ModuleInitializersTests + [CompilerTrait(CompilerFeature.ModuleInitializers)] + public sealed class TargetsTests : CSharpTestBase { + private static readonly CSharpParseOptions s_parseOptions = TestOptions.RegularPreview; + [Fact] public void TargetMustNotBeLocalFunction() { From 23e81d727148b03c744738cee247914413ba9279 Mon Sep 17 00:00:00 2001 From: jnm2 Date: Mon, 11 May 2020 22:13:41 -0400 Subject: [PATCH 35/35] Test both orders of ModuleInitializerAttribute and ConditionalAttribute --- .../ModuleInitializers/ModuleInitializersTests.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/ModuleInitializersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/ModuleInitializersTests.cs index c0e2bebb3f878..f4080a50ed14a 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/ModuleInitializersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ModuleInitializers/ModuleInitializersTests.cs @@ -729,8 +729,11 @@ public void ModuleInitializerMethodIncludedByConditionalAttribute() class C { + [System.Diagnostics.Conditional(""INCLUDE""), ModuleInitializer] + internal static void Preceding() => Console.WriteLine(""C.Preceding""); + [ModuleInitializer, System.Diagnostics.Conditional(""INCLUDE"")] - internal static void M() => Console.WriteLine(""C.M""); + internal static void Following() => Console.WriteLine(""C.Following""); } class Program @@ -741,7 +744,8 @@ class Program namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } } "; CompileAndVerify(source, parseOptions: s_parseOptions, expectedOutput: @" -C.M +C.Preceding +C.Following Program.Main"); } @@ -754,8 +758,11 @@ public void ModuleInitializerMethodExcludedByConditionalAttribute() class C { + [System.Diagnostics.Conditional(""EXCLUDE""), ModuleInitializer] + internal static void Preceding() { } + [ModuleInitializer, System.Diagnostics.Conditional(""EXCLUDE"")] - internal static void M() { } + internal static void Following() { } } namespace System.Runtime.CompilerServices { class ModuleInitializerAttribute : System.Attribute { } }