From 3255afaa9efd6e6deac635160fdddf122003732c Mon Sep 17 00:00:00 2001 From: jnm2 Date: Tue, 14 Apr 2020 22:33:18 -0400 Subject: [PATCH] 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) + ); + } + } +}