From c3465bef0c396cab4b5d754a64103a398c7ffa1c Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Wed, 17 May 2023 15:17:46 -0700 Subject: [PATCH] Remove InterceptableAttribute (#68213) --- docs/features/interceptors.md | 51 +-- .../CSharp/Portable/CSharpResources.resx | 6 - .../CSharp/Portable/Errors/ErrorCode.cs | 1 - .../CSharp/Portable/Errors/ErrorFacts.cs | 2 - .../Generated/ErrorFacts.Generated.cs | 1 - .../LocalRewriter/LocalRewriter_Call.cs | 7 - .../MethodWellKnownAttributeData.cs | 16 - .../Portable/Symbols/ErrorMethodSymbol.cs | 2 - .../FunctionPointerMethodSymbol.cs | 1 - .../Symbols/Metadata/PE/PEMethodSymbol.cs | 126 ++---- .../CSharp/Portable/Symbols/MethodSymbol.cs | 5 - .../Symbols/NativeIntegerTypeSymbol.cs | 2 - .../Symbols/ReducedExtensionMethodSymbol.cs | 2 - .../Retargeting/RetargetingMethodSymbol.cs | 2 - .../Symbols/SignatureOnlyMethodSymbol.cs | 2 - .../SourceMethodSymbolWithAttributes.cs | 10 - .../Symbols/SubstitutedMethodSymbol.cs | 2 - .../SynthesizedEntryPointSymbol.cs | 2 - .../SynthesizedGlobalMethodSymbol.cs | 2 - .../SynthesizedInstanceMethodSymbol.cs | 2 - .../SynthesizedIntrinsicOperatorSymbol.cs | 7 - .../SynthesizedStaticConstructor.cs | 2 - .../Portable/xlf/CSharpResources.cs.xlf | 10 - .../Portable/xlf/CSharpResources.de.xlf | 10 - .../Portable/xlf/CSharpResources.es.xlf | 10 - .../Portable/xlf/CSharpResources.fr.xlf | 10 - .../Portable/xlf/CSharpResources.it.xlf | 10 - .../Portable/xlf/CSharpResources.ja.xlf | 10 - .../Portable/xlf/CSharpResources.ko.xlf | 10 - .../Portable/xlf/CSharpResources.pl.xlf | 10 - .../Portable/xlf/CSharpResources.pt-BR.xlf | 10 - .../Portable/xlf/CSharpResources.ru.xlf | 10 - .../Portable/xlf/CSharpResources.tr.xlf | 10 - .../Portable/xlf/CSharpResources.zh-Hans.xlf | 10 - .../Portable/xlf/CSharpResources.zh-Hant.xlf | 10 - .../Semantic/Semantics/InterceptorsTests.cs | 399 ++++++------------ .../Test/Syntax/Diagnostics/DiagnosticTest.cs | 2 - .../InternalUtilities/EnumUtilties.cs | 13 - .../ThreadSafeFlagOperations.cs | 16 - .../Core/Portable/MetadataReader/PEModule.cs | 5 - .../Attributes/AttributeDescription.cs | 1 - .../CSharpLspBuildOnlyDiagnostics.cs | 1 - .../Symbols/EECompilationContextMethod.cs | 2 - .../Symbols/EEMethodSymbol.cs | 2 - .../Symbols/PlaceholderMethodSymbol.cs | 2 - 45 files changed, 169 insertions(+), 657 deletions(-) diff --git a/docs/features/interceptors.md b/docs/features/interceptors.md index 6335788b1fc33..675eb8642ac1d 100644 --- a/docs/features/interceptors.md +++ b/docs/features/interceptors.md @@ -19,7 +19,6 @@ c.InterceptableMethod(1); // prints "interceptable 1" class C { - [Interceptable] public void InterceptableMethod(int param) { Console.WriteLine($"interceptable {param}"); @@ -47,49 +46,6 @@ static class D ## Detailed design [design]: #detailed-design -### InterceptableAttribute - -A method can indicate that its calls can be *intercepted* by including `[Interceptable]` on its declaration. - -PROTOTYPE(ic): For now, if a call is intercepted to a method which lacks this attribute, a warning is reported, and interception still occurs. This may be changed to an error in the future. - -```cs -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Method)] - public sealed class InterceptableAttribute : Attribute { } -} -``` - -#### PROTOTYPE(ic): Use an assembly attribute instead? -The main reason we want something like `[Interceptable]` is so that users can better reason about *which calls might be getting intercepted or not*. We don't think there's a meaningful *security* concern which is addressed by `[Interceptable]`--if something untrusted has the ability to add source files to your build, taking away the ability for them to intercept certain calls doesn't really make a difference. - -It's been suggested that `[Interceptable]` on method declarations is the wrong point of control. Some SG authors will have good reason to want to intercept a call to a method from a library they don't own--for example, EF wanting to intercept calls to IQueryable extensions. It shouldn't be necessary for those authors to have to request the library authors to add an attribute before they can start doing it. - -One option to address this is to remove `[Interceptable]` from the design and not provide any mechanism for limiting which calls can be intercepted or not. - -Another option would be to expose an assembly attribute instead. - -```cs -namespace System.Runtime.CompilerServices -{ - /// If present, indicates the set of types whose methods can have their calls intercepted in the current compilation. - /// When this attribute is not present, methods on any type can have their calls intercepted. - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] - public sealed class AllowInterception(params Type[] types) : Attribute { } -} - -[assembly: AllowInterception(typeof(EndpointRouteBuilderExtensions))] -``` - -In order to intercept a classic extension method call, the extension type must be provided to this attribute, not the `this` parameter type. - -We specify `AllowMultiple = false` here to imply that the attribute is supposed to be hand-authored by the user. It's not meant for generators to use this to *opt themselves in* to being able to intercept things--it's for the user to state once and comprehensively which things can be intercepted. - -In such a scheme, it's not clear how often users would actually want to go to the trouble of writing the attribute--particularly since the process of writing and maintaining it would simply be to run source generators, review the "not interceptable" errors, and add the related types to this attribute. Is that useful to users in practice? - -Another alternative here might be to use `AllowMultiple = true`, require in practice that generators produce these attributes (i.e. disallow intercepting in the current compilation if this attribute isn't used in it), and let users search for usages of the attribute to get a sense of which calls may be getting intercepted in their project. - ### InterceptsLocationAttribute A method indicates that it is an *interceptor* by adding one or more `[InterceptsLocation]` attributes. These attributes refer to the source locations of the calls it intercepts. @@ -104,10 +60,12 @@ namespace System.Runtime.CompilerServices } ``` +Any "ordinary method" (i.e. with `MethodKind.Ordinary`) can have its calls intercepted. + `[InterceptsLocation]` attributes included in source are emitted to the resulting assembly, just like other custom attributes. PROTOTYPE(ic): We may want to recognize `file class InterceptsLocationAttribute` as a valid declaration of the attribute, to allow generators to bring the attribute in without conflicting with other generators which may also be bringing the attribute in. See open question in [User opt-in](#user-opt-in). -https://github.com/dotnet/roslyn/issues/67079 is a bug which causes file-local source declarations of well-known attributes to be generally treated as known. When that bug is fixed, we may want to single out one or both of `InterceptableAttribute` and `InterceptsLocationAttribute` as "recognized, even though they are file-local". +https://github.com/dotnet/roslyn/issues/67079 is a bug which causes file-local source declarations of well-known attributes to be generally treated as known. When that bug is fixed, we may want to single out `InterceptsLocationAttribute` as "recognized, even though they are file-local". #### File paths @@ -146,7 +104,6 @@ using System.Runtime.CompilerServices; class C { - [Interceptable] public static void InterceptableMethod(T1 t) => throw null!; } @@ -160,7 +117,7 @@ static class Program static class D { - [InterceptsLocation("Program.cs", 13, 11)] + [InterceptsLocation("Program.cs", 12, 11)] public static void Interceptor1(object s) => throw null!; } ``` diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index edc9246550ab2..cb84d87071688 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -7505,12 +7505,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ A switch expression arm does not begin with a 'case' keyword. - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Method '{0}' cannot be used as an interceptor because it or its containing type has type parameters. diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 1837e9ca2ee51..8079af5b70a90 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -2193,7 +2193,6 @@ internal enum ErrorCode ERR_UnsupportedPrimaryConstructorParameterCapturingRefAny = 9136, // PROTOTYPE(ic): pack errors - WRN_CallNotInterceptable = 27000, ERR_InterceptorCannotBeGeneric = 27001, ERR_InterceptorPathNotInCompilation = 27002, ERR_InterceptorPathNotInCompilationWithCandidate = 27003, diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs index 3575d881959c1..8f040b84da993 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs @@ -532,7 +532,6 @@ internal static int GetWarningLevel(ErrorCode code) case ErrorCode.WRN_ParamsArrayInLambdaOnly: case ErrorCode.WRN_CapturedPrimaryConstructorParameterPassedToBase: case ErrorCode.WRN_UnreadPrimaryConstructorParameter: - case ErrorCode.WRN_CallNotInterceptable: case ErrorCode.WRN_InterceptorSignatureMismatch: case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnInterceptor: case ErrorCode.WRN_NullabilityMismatchInParameterTypeOnInterceptor: @@ -585,7 +584,6 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code) case ErrorCode.ERR_EncUpdateFailedDelegateTypeChanged: case ErrorCode.ERR_CannotBeConvertedToUtf8: case ErrorCode.ERR_FileTypeNonUniquePath: - case ErrorCode.WRN_CallNotInterceptable: case ErrorCode.ERR_InterceptorSignatureMismatch: case ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter: case ErrorCode.ERR_InterceptorMustNotHaveThisParameter: diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs index b726052c876be..84b874e035343 100644 --- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs @@ -315,7 +315,6 @@ public static bool IsWarning(ErrorCode code) case ErrorCode.WRN_CapturedPrimaryConstructorParameterPassedToBase: case ErrorCode.WRN_UnreadPrimaryConstructorParameter: case ErrorCode.WRN_AddressOfInAsync: - case ErrorCode.WRN_CallNotInterceptable: case ErrorCode.WRN_InterceptorSignatureMismatch: case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnInterceptor: case ErrorCode.WRN_NullabilityMismatchInParameterTypeOnInterceptor: diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index a3e3da05595f0..9d164bd43ab0f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -154,13 +154,6 @@ private void InterceptCallAndAdjustArguments( Debug.Assert(interceptableLocation != null); Debug.Assert(interceptor.Arity == 0); - if (!method.IsInterceptable) - { - // PROTOTYPE(ic): Eventually we may want this to be an error. - // For now it's convenient to just warn so we can experiment with intercepting APIs that haven't yet been marked. - this._diagnostics.Add(ErrorCode.WRN_CallNotInterceptable, attributeLocation, method); - } - var containingMethod = this._factory.CurrentFunction; Debug.Assert(containingMethod is not null); diff --git a/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/MethodWellKnownAttributeData.cs b/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/MethodWellKnownAttributeData.cs index f2a1894a2df53..e95f295b21e87 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/MethodWellKnownAttributeData.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/MethodWellKnownAttributeData.cs @@ -149,21 +149,5 @@ public UnmanagedCallersOnlyAttributeData? UnmanagedCallersOnlyAttributeData SetDataStored(); } } - - private bool _hasInterceptableAttribute; - public bool HasInterceptableAttribute - { - get - { - VerifySealed(expected: true); - return _hasInterceptableAttribute; - } - set - { - VerifySealed(expected: false); - _hasInterceptableAttribute = value; - SetDataStored(); - } - } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/ErrorMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/ErrorMethodSymbol.cs index ef7005725a1bd..595fbd4211769 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ErrorMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ErrorMethodSymbol.cs @@ -276,8 +276,6 @@ internal override bool GenerateDebugInfo internal sealed override bool IsNullableAnalysisEnabled() => false; - internal override bool IsInterceptable => false; - protected override bool HasSetsRequiredMembersImpl { get diff --git a/src/Compilers/CSharp/Portable/Symbols/FunctionPointers/FunctionPointerMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/FunctionPointers/FunctionPointerMethodSymbol.cs index 1d6b086df5445..2e35ac687077e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/FunctionPointers/FunctionPointerMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/FunctionPointers/FunctionPointerMethodSymbol.cs @@ -831,7 +831,6 @@ public override bool IsVararg public override FlowAnalysisAnnotations FlowAnalysisAnnotations => FlowAnalysisAnnotations.None; internal override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false) => false; internal override bool IsMetadataVirtual(bool ignoreInterfaceImplementationChanges = false) => false; - internal sealed override bool IsInterceptable => false; internal sealed override UnmanagedCallersOnlyAttributeData? GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => null; internal override bool GenerateDebugInfo => throw ExceptionUtilities.Unreachable(); diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs index 67a870903fa9c..6bd5fe8a05be1 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs @@ -45,12 +45,10 @@ public SignatureData(SignatureHeader header, ImmutableArray par // This type is used to compact many different bits of information efficiently. private struct PackedFlags { - // We currently pack everything into a 64-bit long with the following layout: + // We currently pack everything into a 32-bit int with the following layout: // - // |________|________|________|_______|A|z|y|x|w|v|u|t|s|r|q|p|ooo|n|m|l|k|j|i|h|g|f|e|d|c|b|aaaaa| + // |y|x|w|v|u|t|s|r|q|p|ooo|n|m|l|k|j|i|h|g|f|e|d|c|b|aaaaa| // - // _ = unused - // // a = method kind. 5 bits. // b = method kind populated. 1 bit. // @@ -78,49 +76,38 @@ private struct PackedFlags // w = IsSetsRequiredMembersPopulated. 1 bit. // x = IsUnscopedRef. 1 bit. // y = IsUnscopedRefPopulated. 1 bit. - // z = IsInterceptable. 1 bit. - // A = IsInterceptablePopulated. 1 bit. - // 31 bits remain for future purposes. - - // PROTOTYPE(ic): consider reverting back to 'int' for these flags. - // - There may not be a need to cache 'IsInterceptable' on the symbol. We could just look it up from attributes each time. - // Since the number of calls which are intercepted is relatively small, this may be a negligible additional cost. - // - Otherwise, there may be more space efficient method of storing the flags which we should be using instead. - // For example, writing a byte is atomic, so if multiple *bits of information* aren't being stored independently in it, - // we could store 'IsInterceptable' in a 'ThreeState' field, for example. + // 2 bits remain for future purposes. private const int MethodKindOffset = 0; - private const long MethodKindMask = 0x1F; - - private const long MethodKindIsPopulatedBit = 0x1L << 5; - private const long IsExtensionMethodBit = 0x1L << 6; - private const long IsExtensionMethodIsPopulatedBit = 0x1L << 7; - private const long IsExplicitFinalizerOverrideBit = 0x1L << 8; - private const long IsExplicitClassOverrideBit = 0x1L << 9; - private const long IsExplicitOverrideIsPopulatedBit = 0x1L << 10; - private const long IsObsoleteAttributePopulatedBit = 0x1L << 11; - private const long IsCustomAttributesPopulatedBit = 0x1L << 12; - private const long IsUseSiteDiagnosticPopulatedBit = 0x1L << 13; - private const long IsConditionalPopulatedBit = 0x1L << 14; - private const long IsOverriddenOrHiddenMembersPopulatedBit = 0x1L << 15; - private const long IsReadOnlyBit = 0x1L << 16; - private const long IsReadOnlyPopulatedBit = 0x1L << 17; + private const int MethodKindMask = 0x1F; + + private const int MethodKindIsPopulatedBit = 0x1 << 5; + private const int IsExtensionMethodBit = 0x1 << 6; + private const int IsExtensionMethodIsPopulatedBit = 0x1 << 7; + private const int IsExplicitFinalizerOverrideBit = 0x1 << 8; + private const int IsExplicitClassOverrideBit = 0x1 << 9; + private const int IsExplicitOverrideIsPopulatedBit = 0x1 << 10; + private const int IsObsoleteAttributePopulatedBit = 0x1 << 11; + private const int IsCustomAttributesPopulatedBit = 0x1 << 12; + private const int IsUseSiteDiagnosticPopulatedBit = 0x1 << 13; + private const int IsConditionalPopulatedBit = 0x1 << 14; + private const int IsOverriddenOrHiddenMembersPopulatedBit = 0x1 << 15; + private const int IsReadOnlyBit = 0x1 << 16; + private const int IsReadOnlyPopulatedBit = 0x1 << 17; private const int NullableContextOffset = 18; - private const long NullableContextMask = 0x7; - private const long DoesNotReturnBit = 0x1L << 21; - private const long IsDoesNotReturnPopulatedBit = 0x1L << 22; - private const long IsMemberNotNullPopulatedBit = 0x1L << 23; - private const long IsInitOnlyBit = 0x1L << 24; - private const long IsInitOnlyPopulatedBit = 0x1L << 25; - private const long IsUnmanagedCallersOnlyAttributePopulatedBit = 0x1L << 26; - private const long HasSetsRequiredMembersBit = 0x1L << 27; - private const long HasSetsRequiredMembersPopulatedBit = 0x1L << 28; - private const long IsUnscopedRefBit = 0x1L << 29; - private const long IsUnscopedRefPopulatedBit = 0x1L << 30; - private const long IsInterceptableBit = 0x1L << 31; - private const long IsInterceptablePopulatedBit = 0x1L << 32; - - private long _bits; + private const int NullableContextMask = 0x7; + private const int DoesNotReturnBit = 0x1 << 21; + private const int IsDoesNotReturnPopulatedBit = 0x1 << 22; + private const int IsMemberNotNullPopulatedBit = 0x1 << 23; + private const int IsInitOnlyBit = 0x1 << 24; + private const int IsInitOnlyPopulatedBit = 0x1 << 25; + private const int IsUnmanagedCallersOnlyAttributePopulatedBit = 0x1 << 26; + private const int HasSetsRequiredMembersBit = 0x1 << 27; + private const int HasSetsRequiredMembersPopulatedBit = 0x1 << 28; + private const int IsUnscopedRefBit = 0x1 << 29; + private const int IsUnscopedRefPopulatedBit = 0x1 << 30; + + private int _bits; public MethodKind MethodKind { @@ -131,8 +118,8 @@ public MethodKind MethodKind set { - Debug.Assert((long)value == ((long)value & MethodKindMask)); - _bits = (_bits & ~(MethodKindMask << MethodKindOffset)) | (((long)value & MethodKindMask) << MethodKindOffset) | MethodKindIsPopulatedBit; + Debug.Assert((int)value == ((int)value & MethodKindMask)); + _bits = (_bits & ~(MethodKindMask << MethodKindOffset)) | (((int)value & MethodKindMask) << MethodKindOffset) | MethodKindIsPopulatedBit; } } @@ -159,8 +146,6 @@ public MethodKind MethodKind public bool HasSetsRequiredMembersPopulated => (_bits & HasSetsRequiredMembersPopulatedBit) != 0; public bool IsUnscopedRef => (_bits & IsUnscopedRefBit) != 0; public bool IsUnscopedRefPopulated => (_bits & IsUnscopedRefPopulatedBit) != 0; - public bool IsInterceptable => (_bits & IsInterceptableBit) != 0; - public bool IsInterceptablePopulated => (_bits & IsInterceptablePopulatedBit) != 0; #if DEBUG static PackedFlags() @@ -171,36 +156,36 @@ static PackedFlags() } #endif - private static bool BitsAreUnsetOrSame(long bits, long mask) + private static bool BitsAreUnsetOrSame(int bits, int mask) { return (bits & mask) == 0 || (bits & mask) == mask; } public void InitializeIsExtensionMethod(bool isExtensionMethod) { - var bitsToSet = (isExtensionMethod ? IsExtensionMethodBit : 0) | IsExtensionMethodIsPopulatedBit; + int bitsToSet = (isExtensionMethod ? IsExtensionMethodBit : 0) | IsExtensionMethodIsPopulatedBit; Debug.Assert(BitsAreUnsetOrSame(_bits, bitsToSet)); ThreadSafeFlagOperations.Set(ref _bits, bitsToSet); } public void InitializeIsReadOnly(bool isReadOnly) { - var bitsToSet = (isReadOnly ? IsReadOnlyBit : 0) | IsReadOnlyPopulatedBit; + int bitsToSet = (isReadOnly ? IsReadOnlyBit : 0) | IsReadOnlyPopulatedBit; Debug.Assert(BitsAreUnsetOrSame(_bits, bitsToSet)); ThreadSafeFlagOperations.Set(ref _bits, bitsToSet); } public void InitializeMethodKind(MethodKind methodKind) { - Debug.Assert((long)methodKind == ((long)methodKind & MethodKindMask)); - var bitsToSet = (((long)methodKind & MethodKindMask) << MethodKindOffset) | MethodKindIsPopulatedBit; + Debug.Assert((int)methodKind == ((int)methodKind & MethodKindMask)); + int bitsToSet = (((int)methodKind & MethodKindMask) << MethodKindOffset) | MethodKindIsPopulatedBit; Debug.Assert(BitsAreUnsetOrSame(_bits, bitsToSet)); ThreadSafeFlagOperations.Set(ref _bits, bitsToSet); } public void InitializeIsExplicitOverride(bool isExplicitFinalizerOverride, bool isExplicitClassOverride) { - var bitsToSet = + int bitsToSet = (isExplicitFinalizerOverride ? IsExplicitFinalizerOverrideBit : 0) | (isExplicitClassOverride ? IsExplicitClassOverrideBit : 0) | IsExplicitOverrideIsPopulatedBit; @@ -240,12 +225,12 @@ public bool TryGetNullableContext(out byte? value) public bool SetNullableContext(byte? value) { - return ThreadSafeFlagOperations.Set(ref _bits, (((long)value.ToNullableContextFlags() & NullableContextMask) << NullableContextOffset)); + return ThreadSafeFlagOperations.Set(ref _bits, (((int)value.ToNullableContextFlags() & NullableContextMask) << NullableContextOffset)); } public bool InitializeDoesNotReturn(bool value) { - var bitsToSet = IsDoesNotReturnPopulatedBit; + int bitsToSet = IsDoesNotReturnPopulatedBit; if (value) bitsToSet |= DoesNotReturnBit; return ThreadSafeFlagOperations.Set(ref _bits, bitsToSet); @@ -258,7 +243,7 @@ public void SetIsMemberNotNullPopulated() public void InitializeIsInitOnly(bool isInitOnly) { - var bitsToSet = (isInitOnly ? IsInitOnlyBit : 0) | IsInitOnlyPopulatedBit; + int bitsToSet = (isInitOnly ? IsInitOnlyBit : 0) | IsInitOnlyPopulatedBit; Debug.Assert(BitsAreUnsetOrSame(_bits, bitsToSet)); ThreadSafeFlagOperations.Set(ref _bits, bitsToSet); } @@ -270,7 +255,7 @@ public void SetIsUnmanagedCallersOnlyAttributePopulated() public bool InitializeSetsRequiredMembersBit(bool value) { - var bitsToSet = HasSetsRequiredMembersPopulatedBit; + int bitsToSet = HasSetsRequiredMembersPopulatedBit; if (value) bitsToSet |= HasSetsRequiredMembersBit; return ThreadSafeFlagOperations.Set(ref _bits, bitsToSet); @@ -278,19 +263,11 @@ public bool InitializeSetsRequiredMembersBit(bool value) public bool InitializeIsUnscopedRef(bool value) { - var bitsToSet = IsUnscopedRefPopulatedBit; + int bitsToSet = IsUnscopedRefPopulatedBit; if (value) bitsToSet |= IsUnscopedRefBit; return ThreadSafeFlagOperations.Set(ref _bits, bitsToSet); } - - public bool InitializeInterceptable(bool value) - { - var bitsToSet = IsInterceptablePopulatedBit; - if (value) bitsToSet |= IsInterceptableBit; - - return ThreadSafeFlagOperations.Set(ref _bits, bitsToSet); - } } /// @@ -1672,21 +1649,6 @@ internal sealed override bool HasUnscopedRefAttribute } } - internal sealed override bool IsInterceptable - { - get - { - if (!_packedFlags.IsInterceptablePopulated) - { - var moduleSymbol = _containingType.ContainingPEModule; - bool interceptable = moduleSymbol.Module.HasInterceptableAttribute(_handle); - _packedFlags.InitializeInterceptable(interceptable); - } - - return _packedFlags.IsInterceptable; - } - } - internal sealed override bool UseUpdatedEscapeRules => ContainingModule.UseUpdatedEscapeRules; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs index d8fd84a9cc348..e359a98d68fa7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs @@ -94,11 +94,6 @@ public virtual bool IsGenericMethod /// internal virtual bool IsDirectlyExcludedFromCodeCoverage { get => false; } - /// - /// True if the method is annotated with the `[Interceptable]` attribute. - /// - internal abstract bool IsInterceptable { get; } - /// /// If a method is annotated with `[MemberNotNull(...)]` attributes, returns the list of members /// listed in those attributes. diff --git a/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs index 5b93f8268edd8..7a296e86a1722 100644 --- a/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs @@ -349,8 +349,6 @@ public override ImmutableArray Parameters internal override UnmanagedCallersOnlyAttributeData? GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => UnderlyingMethod.GetUnmanagedCallersOnlyAttributeData(forceComplete); - internal override bool IsInterceptable => UnderlyingMethod.IsInterceptable; - public override Symbol? AssociatedSymbol => _associatedSymbol; internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree) diff --git a/src/Compilers/CSharp/Portable/Symbols/ReducedExtensionMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/ReducedExtensionMethodSymbol.cs index 76cda79d142d3..f862e7cc8f4e7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ReducedExtensionMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ReducedExtensionMethodSymbol.cs @@ -580,8 +580,6 @@ internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree l internal override bool IsNullableAnalysisEnabled() => throw ExceptionUtilities.Unreachable(); - internal override bool IsInterceptable => throw ExceptionUtilities.Unreachable(); - public override bool Equals(Symbol obj, TypeCompareKind compareKind) { if ((object)this == obj) return true; diff --git a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingMethodSymbol.cs index 30d17e493ca9b..781406109136f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingMethodSymbol.cs @@ -256,8 +256,6 @@ public override ImmutableArray GetReturnTypeAttributes() return _lazyUnmanagedAttributeData; } - internal override bool IsInterceptable => UnderlyingMethod.IsInterceptable; - internal override bool TryGetThisParameter(out ParameterSymbol? thisParameter) { if (!_underlyingMethod.TryGetThisParameter(out var underlyingParameter)) diff --git a/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyMethodSymbol.cs index ebd1f6e3a72a7..279464bc50d4f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/SignatureOnlyMethodSymbol.cs @@ -96,8 +96,6 @@ public SignatureOnlyMethodSymbol( internal sealed override bool IsNullableAnalysisEnabled() => throw ExceptionUtilities.Unreachable(); - internal sealed override bool IsInterceptable => throw ExceptionUtilities.Unreachable(); - #region Not used by MethodSignatureComparer internal override bool GenerateDebugInfo { get { throw ExceptionUtilities.Unreachable(); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 1a2ddbb550c77..48e7d6d79c23b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -597,14 +597,6 @@ private void DecodeWellKnownAttributeAppliedToMethod(ref DecodeWellKnownAttribut diagnostics.Add(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, arguments.AttributeSyntaxOpt.Location); } } - else if (attribute.IsTargetAttribute(this, AttributeDescription.InterceptableAttribute)) - { - if (MethodKind != MethodKind.Ordinary) - { - diagnostics.Add(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, arguments.AttributeSyntaxOpt.Location); - } - arguments.GetOrCreateData().HasInterceptableAttribute = true; - } else if (attribute.IsTargetAttribute(this, AttributeDescription.InterceptsLocationAttribute)) { DecodeInterceptsLocationAttribute(arguments); @@ -1394,8 +1386,6 @@ internal override bool HasSpecialName internal sealed override bool IsDirectlyExcludedFromCodeCoverage => GetDecodedWellKnownAttributeData()?.HasExcludeFromCodeCoverageAttribute == true; - internal sealed override bool IsInterceptable => GetDecodedWellKnownAttributeData()?.HasInterceptableAttribute == true; - internal override bool RequiresSecurityObject { get diff --git a/src/Compilers/CSharp/Portable/Symbols/SubstitutedMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/SubstitutedMethodSymbol.cs index 81740b40b5cf2..4e21bb16912d1 100644 --- a/src/Compilers/CSharp/Portable/Symbols/SubstitutedMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/SubstitutedMethodSymbol.cs @@ -215,8 +215,6 @@ public override ImmutableArray GetReturnTypeAttributes() internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => this.OriginalDefinition.GetUnmanagedCallersOnlyAttributeData(forceComplete); - internal sealed override bool IsInterceptable => UnderlyingMethod.IsInterceptable; - public sealed override Symbol AssociatedSymbol { get diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs index d0c10c5b66771..e69f0c4e5eba5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs @@ -198,8 +198,6 @@ public override bool IsExtensionMethod get { return false; } } - internal override bool IsInterceptable => false; - internal sealed override ObsoleteAttributeData ObsoleteAttributeData { get { return null; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedGlobalMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedGlobalMethodSymbol.cs index d528f319c2a79..873180ce4361c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedGlobalMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedGlobalMethodSymbol.cs @@ -336,8 +336,6 @@ internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree l internal sealed override bool IsNullableAnalysisEnabled() => false; - internal sealed override bool IsInterceptable => false; - protected sealed override bool HasSetsRequiredMembersImpl => throw ExceptionUtilities.Unreachable(); internal sealed override bool HasUnscopedRefAttribute => false; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceMethodSymbol.cs index 0af1191744f22..28ed8edcf2b0d 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceMethodSymbol.cs @@ -42,8 +42,6 @@ public sealed override bool AreLocalsZeroed } } - internal sealed override bool IsInterceptable => false; - internal override bool TryGetThisParameter(out ParameterSymbol thisParameter) { Debug.Assert(!IsStatic); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedIntrinsicOperatorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedIntrinsicOperatorSymbol.cs index 4d428a9bdcc7f..a95e0fcb29572 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedIntrinsicOperatorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedIntrinsicOperatorSymbol.cs @@ -78,13 +78,6 @@ public override bool IsImplicitlyDeclared return true; } } - internal sealed override bool IsInterceptable - { - get - { - return false; - } - } internal override CSharpCompilation DeclaringCompilation { diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedStaticConstructor.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedStaticConstructor.cs index 2251657cfeffd..4cfb133a4d306 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedStaticConstructor.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedStaticConstructor.cs @@ -292,8 +292,6 @@ public override ImmutableArray ExplicitInterfaceImplementations internal override bool IsInitOnly => false; - internal sealed override bool IsInterceptable => false; - public sealed override bool IsImplicitlyDeclared { get diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index f6a3ba9b4f6cd..da6d8187c7b5f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -2187,16 +2187,6 @@ Tato kombinace argumentů parametru může vystavit proměnné, na které odkazuje parametr, mimo obor jejich deklarace - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. Atribut CallerArgumentExpressionAttribute použitý u parametru {0} nebude mít žádný účinek. Argument je použitý s neplatným názvem parametru. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 4775f369b6c8e..396c299281a55 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -2187,16 +2187,6 @@ Diese Kombination aus Argumenten führt möglicherweise dazu, dass vom Parameter referenzierte Variablen außerhalb ihres Deklarationsbereichs verfügbar gemacht werden. - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. Das CallerArgumentExpressionAttribute, das auf den Parameter „{0}“ angewendet wird, hat keine Auswirkungen. Es wird mit einem ungültigen Parameternamen angewendet. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index c98f2610d8cdb..8edd7a5faf67a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -2187,16 +2187,6 @@ Esta combinación de argumentos puede exponer variables a las que el parámetro hace referencia fuera de su ámbito de declaración - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. El atributo CallerArgumentExpressionAttribute aplicado al parámetro "{0}" no tendrá ningún efecto. Se ha aplicado con un nombre de parámetro no válido. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 3dd257de8b842..3c5cec296f3be 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -2187,16 +2187,6 @@ Cette combinaison d'arguments pour peut exposer les variables référencées par le paramètre en dehors de la portée de leur déclaration - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. Le CallerArgumentExpressionAttribute appliqué au paramètre « {0} » n’aura aucun effet. Il est appliqué avec un nom de paramètre non valide. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 67c0a4af954dd..78dd268858da4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -2187,16 +2187,6 @@ Questa combinazione di argomenti potrebbe esporre variabili a cui fa riferimento il parametro al di fuori del relativo ambito di dichiarazione - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. CallerArgumentExpressionAttribute applicato al parametro '{0}' non avrà alcun effetto. È applicato con un nome di parametro non valido. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 2e39692f5e759..8f241066b237f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -2187,16 +2187,6 @@ この引数の組み合わせは、パラメーターによって参照される変数が宣言のスコープ外に公開される可能性があります - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. パラメーター '{0}' に適用された CallerArgumentExpressionAttribute は、無効なパラメーター名で適用されているため無効となります diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 43a4c8786a050..d53732825fe84 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -2187,16 +2187,6 @@ 이 인수 조합은 선언 범위 외부의 매개 변수에서 참조하는 변수를 노출할 수 있습니다. - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. 매개 변수 '{0}'에 적용된 CallerArgumentExpressionAttribute는 효과가 없습니다. 잘못된 매개 변수 이름으로 적용되었습니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 3d12114c23d92..0bed07960c287 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -2187,16 +2187,6 @@ Ta kombinacja argumentów może uwidaczniać zmienne przywoływane przez parametr poza zakresem deklaracji - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. Atrybut CallerArgumentExpressionAttribute zastosowany do parametru "{0}" nie odniesie żadnego skutku. Zastosowano go z nieprawidłową nazwą parametru. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index f9164b202ad58..7530b201271fc 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -2187,16 +2187,6 @@ Essa combinação de argumentos pode expor variáveis referenciadas por parâmetro fora de seu escopo de declaração - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. O CallerArgumentExpressionAttribute aplicado ao parâmetro '{0}' não terá efeito. Ele é aplicado com um nome de parâmetro inválido. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index f89e28656b89f..59b8a3165f8a3 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -2187,16 +2187,6 @@ Эта комбинация аргументов может представить переменные, на которые ссылается параметр, за пределами области их объявления. - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. Применение класса CallerArgumentExpressionAttribute к параметру "{0}" не подействует, поскольку он применен с недопустимым именем параметра. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 978a4683aa769..b93ec0247f35c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -2187,16 +2187,6 @@ Bu argüman kombinasyonu, parametre tarafından başvurulan değişkenleri bildirim kapsamı dışında gösterebilir. - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. '{0}' parametresine uygulanan CallerArgumentExpressionAttribute hiçbir etkiye sahip olmaz. Geçersiz bir parametre adıyla uygulanır. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 48e4507666e0a..54497b786a63f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -2187,16 +2187,6 @@ 这种参数组合可能会在变量声明范围之外公开由参数引用的变量 - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. 应用于参数“{0}”的 CallerArgumentExpressionAttribute 将不起任何作用。它采用了无效的参数名。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index e019cec7f53e1..84961b72eba18 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -2187,16 +2187,6 @@ 此引數組合會在其宣告範圍外公開參數所參考的變數 - - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to '{0}' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - - - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - Call to a method is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - - The CallerArgumentExpressionAttribute applied to parameter '{0}' will have no effect. It is applied with an invalid parameter name. 套用到參數 '{0}' 的 CallerArgumentExpressionAttribute 將沒有效果。它套用了不正確的參數名稱。 diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterceptorsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterceptorsTests.cs index b352f04e79e9d..00c14652a8532 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterceptorsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterceptorsTests.cs @@ -17,9 +17,6 @@ public class InterceptorsTests : CSharpTestBase private static readonly (string, string) s_attributesSource = (""" namespace System.Runtime.CompilerServices; - [AttributeUsage(AttributeTargets.Method)] - public sealed class InterceptableAttribute : Attribute { } - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] public sealed class InterceptsLocationAttribute : Attribute { @@ -29,37 +26,6 @@ public InterceptsLocationAttribute(string filePath, int line, int character) } """, "attributes.cs"); - [Fact] - public void IsInterceptable() - { - var source = """ - using System.Runtime.CompilerServices; - using System; - - class C - { - [Interceptable] - public static void InterceptableMethod() { Console.Write("interceptable"); } - - public static void NotInterceptable() { Console.Write("not interceptable"); } - } - """; - - var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, symbolValidator: verify, sourceSymbolValidator: verify); - verifier.VerifyDiagnostics(); - - void verify(ModuleSymbol module) - { - var method = module.GlobalNamespace.GetMember("C.InterceptableMethod"); - Assert.True(method.IsInterceptable); - Assert.Equal(MethodKind.Ordinary, method.MethodKind); - - method = module.GlobalNamespace.GetMember("C.NotInterceptable"); - Assert.False(method.IsInterceptable); - Assert.Equal(MethodKind.Ordinary, method.MethodKind); - } - } - [Fact] public void SelfInterception() { @@ -74,7 +40,7 @@ public static void Main() InterceptableMethod(); } - [Interceptable] + [InterceptsLocation("Program.cs", 8, 9)] public static void InterceptableMethod() { Console.Write(1); } } @@ -92,7 +58,7 @@ public void StaticInterceptable_StaticInterceptor_NoParameters() class C { - [Interceptable] + public static void InterceptableMethod() { Console.Write("interceptable"); } public static void Main() @@ -120,7 +86,7 @@ public void Accessibility_01() class C { - [Interceptable] + public static void InterceptableMethod() { Console.Write("interceptable"); } public static void Main() @@ -147,12 +113,11 @@ public void Accessibility_02() { // An interceptor declared within a file-local type can intercept a call even if the call site can't normally refer to the file-local type. var source1 = """ - using System.Runtime.CompilerServices; using System; class C { - [Interceptable] + public static void InterceptableMethod() { Console.Write("interceptable"); } public static void Main() @@ -168,7 +133,7 @@ public static void Main() file class D { - [InterceptsLocation("Program.cs", 11, 9)] + [InterceptsLocation("Program.cs", 10, 9)] public static void Interceptor1() { Console.Write("interceptor 1"); } } """; @@ -180,6 +145,7 @@ file class D [Fact] public void FileLocalAttributeDefinitions_01() { + // Treat a file-local declaration of InterceptsLocationAttribute as a well-known attribute within the declaring compilation. var source = """ using System; using System.Runtime.CompilerServices; @@ -188,7 +154,6 @@ public void FileLocalAttributeDefinitions_01() class C { - [Interceptable] public static void M() => throw null!; } @@ -203,7 +168,6 @@ public static void M() namespace System.Runtime.CompilerServices { - file class InterceptableAttribute : Attribute { } file class InterceptsLocationAttribute : Attribute { public InterceptsLocationAttribute(string filePath, int line, int character) { } @@ -215,65 +179,62 @@ public InterceptsLocationAttribute(string filePath, int line, int character) { } verifier.VerifyDiagnostics(); } + /// + /// File-local InterceptsLocationAttribute from another compilation is not considered to *duplicate* an interception, even if it is inherited. + /// See also . + /// [Fact] public void FileLocalAttributeDefinitions_02() { - var source0 = """ + var source1 = """ using System.Runtime.CompilerServices; + using System; + + var c = new C(); + c.M(); public class C { - [Interceptable] - public static void M() => throw null!; - } + public void M() => Console.Write(1); + [InterceptsLocation("Program.cs", 5, 3)] + public virtual void Interceptor() => throw null!; + } + namespace System.Runtime.CompilerServices { - file class InterceptableAttribute : Attribute { } + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(string filePath, int line, int character) + { + } + } } """; - var source1 = """ - using System; - using System.Runtime.CompilerServices; + // Inherited attribute on 'override void Interceptor' from other compilation doesn't cause a call in this compilation to be intercepted. + var source2 = """ - C.M(); - static class D - { - [InterceptsLocation("File1.cs", 4, 3)] - public static void M() - { - Console.Write(1); - } - } + // leading blank lines for alignment with the call in the other compilation. + var d = new D(); + d.M(); - namespace System.Runtime.CompilerServices + class D : C { - file class InterceptsLocationAttribute : Attribute - { - public InterceptsLocationAttribute(string filePath, int line, int character) { } - } + public override void Interceptor() => throw null!; } """; - var verifier = CompileAndVerify(new[] { (source0, "File0.cs"), (source1, "File1.cs") }, expectedOutput: "1"); - verifier.VerifyDiagnostics(); - - var comp0 = CreateCompilation((source0, "File0.cs")); - comp0.VerifyEmitDiagnostics(); + var comp1 = CreateCompilation((source1, "Program.cs")); + comp1.VerifyEmitDiagnostics(); - var verifier1 = CompileAndVerify((source1, "File1.cs"), new[] { comp0.ToMetadataReference() }, expectedOutput: "1"); - verifier1.VerifyDiagnostics(); + var comp2Verifier = CompileAndVerify((source2, "Program.cs"), references: new[] { comp1.ToMetadataReference() }, expectedOutput: "1"); + comp2Verifier.VerifyDiagnostics(); - // PROTOTYPE(ic): https://github.com/dotnet/roslyn/issues/67079 - // We are generally treating file-local definitions in source as matching the names of well-known attributes. - // Once the type is emitted to metadata and read back in, we no longer recognize it as the same attribute due to name mangling. - var verifier1_1 = CompileAndVerify((source1, "File1.cs"), new[] { comp0.EmitToImageReference() }, expectedOutput: "1"); - verifier1_1.VerifyDiagnostics( - // File1.cs(8,6): warning CS27000: Call to 'C.M()' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - // [InterceptsLocation("File1.cs", 4, 3)] - Diagnostic(ErrorCode.WRN_CallNotInterceptable, @"InterceptsLocation(""File1.cs"", 4, 3)").WithArguments("C.M()").WithLocation(8, 6)); + comp2Verifier = CompileAndVerify((source2, "Program.cs"), references: new[] { comp1.EmitToImageReference() }, expectedOutput: "1"); + comp2Verifier.VerifyDiagnostics(); } [Fact] @@ -288,7 +249,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -320,7 +281,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -349,7 +310,7 @@ public void InterceptableInstanceMethod_InterceptorExtensionMethod() class C { - [Interceptable] + public C InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; } } @@ -381,7 +342,7 @@ public void InterceptableInstanceMethod_InterceptorStaticMethod() class C { - [Interceptable] + public C InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; } } @@ -440,7 +401,7 @@ public static void M() public class C { - [Interceptable] + public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); } } @@ -468,7 +429,7 @@ public void DuplicateLocation_01() class C { - [Interceptable] + public static void M() { } } @@ -502,7 +463,7 @@ public void DuplicateLocation_02() class C { - [Interceptable] + public static void M() { } } """; @@ -551,7 +512,7 @@ public void DuplicateLocation_03() class C { - [Interceptable] + public void M() => throw null!; [InterceptsLocation("Program.cs", 5, 3)] @@ -592,7 +553,7 @@ public void DuplicateLocation_04() class C { - [Interceptable] + public static void M() { } } @@ -630,7 +591,7 @@ public void InterceptorVirtual_01() class C { - [Interceptable] + public void M() => throw null!; [InterceptsLocation("Program.cs", 5, 3)] @@ -681,7 +642,7 @@ class C class D : C { - [Interceptable] + public void M() => throw null!; public override void Interceptor() => throw null!; @@ -722,7 +683,7 @@ public void InterceptorOverride_01() class C { - [Interceptable] + public void M() => throw null!; public virtual void Interceptor() => throw null!; @@ -774,7 +735,7 @@ class C class D : C { - [Interceptable] + public void M() => throw null!; [InterceptsLocation("Program.cs", 5, 3)] @@ -814,7 +775,7 @@ public static void Main() C.M(); } - [Interceptable] + public static void M() { } } @@ -853,7 +814,7 @@ public void EmitMetadataOnly_02() class C { - [Interceptable] + public static void M() { } } @@ -882,7 +843,7 @@ public void InterceptsLocationFromMetadata() public class C0 { - [Interceptable] + public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); } static void M0() @@ -901,12 +862,12 @@ public static class D comp0.VerifyEmitDiagnostics(); var source1 = """ - using System.Runtime.CompilerServices; + using System; class C1 { - [Interceptable] + public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); } static void Main() @@ -929,7 +890,7 @@ public void InterceptableDelegateConversion() class C { - [Interceptable] + public C InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; } } @@ -1000,7 +961,7 @@ public static void Main() private static object F = 1; - [Interceptable] + public static string nameof(object param) => throw null!; } @@ -1090,11 +1051,7 @@ static class D } """; var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, expectedOutput: "12"); - // PROTOTYPE(ic): drop warning when InterceptableAttribute is removed from the design. verifier.VerifyDiagnostics( - // Program.cs(16,6): warning CS27000: Call to 'Action.Invoke()' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - // [InterceptsLocation("Program.cs", 10, 9)] - Diagnostic(ErrorCode.WRN_CallNotInterceptable, @"InterceptsLocation(""Program.cs"", 10, 9)").WithArguments("System.Action.Invoke()").WithLocation(16, 6) ); } @@ -1107,7 +1064,7 @@ public void QualifiedNameAtCallSite() class C { - [Interceptable] + public static C InterceptableMethod(C c, string param) { Console.Write("interceptable " + param); return c; } } @@ -1139,7 +1096,7 @@ public void InterceptableStaticMethod_InterceptorExtensionMethod() class C { - [Interceptable] + public static C InterceptableMethod(C c, string param) { Console.Write("interceptable " + param); return c; } } @@ -1176,7 +1133,7 @@ class C { } static class D { - [Interceptable] + public static void InterceptableMethod(this C c) => throw null!; [InterceptsLocation("Program.cs", 5, 3)] @@ -1204,7 +1161,7 @@ class C { } static class D { - [Interceptable] + public static void InterceptableMethod(this C c) => throw null!; [InterceptsLocation("Program.cs", 5, 3)] @@ -1232,7 +1189,7 @@ public static void Main() class C { - [Interceptable] + public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); } [InterceptsLocation("Program.cs", 8, 11)] @@ -1255,7 +1212,7 @@ public void ArgumentLabels() class C { - [Interceptable] + public void InterceptableMethod(string s1, string s2) { Console.Write(s1 + s2); } } @@ -1287,7 +1244,7 @@ public void ParameterNameDifference() class C { - [Interceptable] + public void InterceptableMethod(string s1) => throw null!; } @@ -1319,7 +1276,7 @@ public void ParameterNamesInDifferentOrder() class C { - [Interceptable] + public void InterceptableMethod(string s1, string s2) => throw null!; } @@ -1353,7 +1310,7 @@ public void AttributeArgumentLabels_01() class C { - [Interceptable] + public void InterceptableMethod() => throw null!; } @@ -1384,7 +1341,7 @@ public void AttributeArgumentLabels_02() class C { - [Interceptable] + public void InterceptableMethod() => throw null!; } @@ -1423,7 +1380,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -1448,12 +1405,12 @@ static class D public void InterceptableFromMetadata() { var source1 = """ - using System.Runtime.CompilerServices; + using System; public class C { - [Interceptable] + public C InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; } } """; @@ -1493,7 +1450,7 @@ public void InterceptsLocation_BadMethodKind() static class Program { - [Interceptable] + public static void InterceptableMethod(string param) { } public static void Main() @@ -1528,84 +1485,6 @@ public static string Prop ); } - [Fact] - public void Interceptable_BadMethodKind() - { - var source = """ - using System.Runtime.CompilerServices; - using System; - - interface I1 { } - class C : I1 { } - - static class Program - { - public static void Main() - { - var lambda = [Interceptable] (string param) => { }; // 1 - - InterceptableMethod("call site"); - - [Interceptable] // 2 - static void InterceptableMethod(string param) { Console.Write("interceptable " + param); } - } - - public static string Prop - { - [Interceptable] // 3 - set { } - } - } - """; - var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }); - comp.VerifyDiagnostics( - // Program.cs(11,23): error CS27008: An interceptable method must be an ordinary member method. - // var lambda = [Interceptable] (string param) => { }; // 1 - Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, "Interceptable").WithLocation(11, 23), - // Program.cs(15,10): error CS27008: An interceptable method must be an ordinary member method. - // [Interceptable] // 2 - Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, "Interceptable").WithLocation(15, 10), - // Program.cs(21,10): error CS27008: An interceptable method must be an ordinary member method. - // [Interceptable] // 3 - Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, "Interceptable").WithLocation(21, 10) - ); - } - - [Fact] - public void CallNotInterceptable() - { - var source = """ - using System.Runtime.CompilerServices; - using System; - - class C - { - public C InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; } - } - - static class Program - { - public static void Main() - { - var c = new C(); - c.InterceptableMethod("call site"); - } - } - - static class D - { - [InterceptsLocation("Program.cs", 14, 11)] - public static C Interceptor1(this C c, string param) { Console.Write("interceptor " + param); return c; } - } - """; - var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, expectedOutput: "interceptor call site"); - verifier.VerifyDiagnostics( - // Program.cs(20,6): warning CS27000: Call to 'C.InterceptableMethod(string)' is intercepted, but the method is not marked with 'System.Runtime.CompilerServices.InterceptableAttribute'. - // [InterceptsLocation("Program.cs", 14, 11)] - Diagnostic(ErrorCode.WRN_CallNotInterceptable, @"InterceptsLocation(""Program.cs"", 14, 11)").WithArguments("C.InterceptableMethod(string)").WithLocation(20, 6) - ); - } - [Fact] public void InterceptorCannotBeGeneric_01() { @@ -1616,7 +1495,7 @@ public void InterceptorCannotBeGeneric_01() interface I1 { } class C : I1 { - [Interceptable] + public I1 InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; } } @@ -1652,7 +1531,7 @@ public void InterceptorCannotBeGeneric_02() interface I1 { } class C : I1 { - [Interceptable] + public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); } } @@ -1687,7 +1566,7 @@ public void InterceptorCannotBeGeneric_03() interface I1 { } class C : I1 { - [Interceptable] + public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); } } @@ -1725,7 +1604,7 @@ public void InterceptableGeneric_01() class C { - [Interceptable] + public static void InterceptableMethod(T t) { Console.Write("0"); } } @@ -1758,7 +1637,7 @@ public void InterceptableGeneric_02() class C { - [Interceptable] + public static void InterceptableMethod(T t) { Console.Write("0"); } } @@ -1801,7 +1680,7 @@ public void InterceptableGeneric_03() class C { - [Interceptable] + public static void InterceptableMethod(T t) where T : class => throw null!; } @@ -1834,7 +1713,7 @@ public void InterceptableGeneric_04() class C { - [Interceptable] + public static void InterceptableMethod(T1 t) => throw null!; } @@ -1912,7 +1791,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -1948,7 +1827,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -1983,7 +1862,7 @@ class C { } static class Program { - [Interceptable] + public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; } public static void Main() @@ -2018,7 +1897,7 @@ class C { } static class Program { - [Interceptable] + public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; } public static void Main() @@ -2054,7 +1933,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -2098,7 +1977,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -2142,7 +2021,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -2178,7 +2057,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -2222,7 +2101,7 @@ public static void Main() c.InterceptableMethod ("call site"); } - [Interceptable] + public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; } [InterceptsLocation("Program.cs", 12, 11)] // intercept spaces before 'InterceptableMethod' token @@ -2262,7 +2141,7 @@ public static void Main() c.InterceptableMethod/*comment*/("call site"); } - [Interceptable] + public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; } [InterceptsLocation("Program.cs", 11, 31)] // intercept comment after 'InterceptableMethod' token @@ -2300,7 +2179,7 @@ public static void Main() InterceptableMethod("call site"); } - [Interceptable] + public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; } [InterceptsLocation("Program.cs", 12, 13)] // intercept comment above 'InterceptableMethod' token @@ -2337,7 +2216,7 @@ public static void Main() c.InterceptableMethod("call site"); } - [Interceptable] + public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; } [InterceptsLocation("Program.cs", -1, 1)] // 1 @@ -2385,7 +2264,7 @@ class C : I1 { } static class Program { - [Interceptable] + public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; } public static void Main() @@ -2420,7 +2299,7 @@ public void SignatureMismatch_02() interface I1 { } class C : I1 { - [Interceptable] + public I1 InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; } } @@ -2457,7 +2336,7 @@ public void SignatureMismatch_03() struct S { - [Interceptable] + public void InterceptableMethod(string param) { Console.Write("interceptable " + param); } } @@ -2493,7 +2372,7 @@ public void SignatureMismatch_04() class C { - [Interceptable] + public string? InterceptableMethod(string param) => throw null!; } @@ -2525,10 +2404,10 @@ public void SignatureMismatch_05() class C { - [Interceptable] + public void Method1(string? param1) => throw null!; - [Interceptable] + public string Method2() => throw null!; } @@ -2582,10 +2461,10 @@ public void SignatureMismatch_06() class C { - [Interceptable] + public void Method1(object param1) => throw null!; - [Interceptable] + public dynamic Method2() => throw null!; } @@ -2629,7 +2508,7 @@ public void SignatureMismatch_07() class C { - [Interceptable] + public void Method1((string x, string y) param1) => throw null!; } @@ -2661,7 +2540,7 @@ public void ScopedMismatch_01() class C { - [Interceptable] + public static ref int InterceptableMethod(scoped ref int value) => throw null!; } @@ -2698,7 +2577,7 @@ public void ScopedMismatch_02() class C { - [Interceptable] + public static ref int InterceptableMethod(ref int value) => throw null!; } @@ -2738,7 +2617,7 @@ public void ScopedMismatch_03() class C { - [Interceptable] + public static ref int InterceptableMethod([UnscopedRef] out int value) => throw null!; } @@ -2778,7 +2657,7 @@ public void ScopedMismatch_04() class C { - [Interceptable] + public static ref int InterceptableMethod(out int value) => throw null!; } @@ -2813,7 +2692,7 @@ public void ReferenceEquals_01() static class D { - [Interceptable] + public static bool Interceptable(object? obj1, object? obj2) => throw null!; public static void M0(object? obj1, object? obj2) @@ -2935,7 +2814,7 @@ namespace System { public class Object { - [Interceptable] + public static bool ReferenceEquals(object? obj1, object? obj2) => throw null!; } @@ -2997,7 +2876,7 @@ public void ParamsMismatch_01() class C { - [Interceptable] + public static void InterceptableMethod(params int[] value) => throw null!; } @@ -3041,7 +2920,7 @@ public void ParamsMismatch_02() class C { - [Interceptable] + public static void InterceptableMethod(int[] value) => throw null!; } @@ -3091,7 +2970,7 @@ public void ParamsMismatch_03() class C { - [Interceptable] + public static void InterceptableMethod(int[] value) => throw null!; } @@ -3141,7 +3020,7 @@ public struct S1 public S1() { } public int Field = 1; - [Interceptable] + public void M([InterpolatedStringHandlerArgument("")] CustomHandler c) { Console.Write(0); @@ -3193,7 +3072,7 @@ public struct S1 public S1() { } public int Field = 1; - [Interceptable] + public void M(CustomHandler c) { Console.Write(0); @@ -3246,7 +3125,7 @@ public struct S1 public S1(int field) => Field = field; public int Field = 1; - [Interceptable] + public static void M(S1 s1, S1 s2, [InterpolatedStringHandlerArgument("s1")] CustomHandler c) { Console.Write(0); @@ -3292,7 +3171,7 @@ public void LineDirective_01() class C { - [Interceptable] + public static void InterceptableMethod() { Console.Write("interceptable"); } public static void Main() @@ -3322,7 +3201,7 @@ public void LineDirective_02() class C { - [Interceptable] + public static void InterceptableMethod() { Console.Write("interceptable"); } public static void Main() @@ -3357,7 +3236,7 @@ public void ObsoleteInterceptor() class C { - [Interceptable] + public static void M() => throw null!; } @@ -3385,7 +3264,7 @@ public void CallerInfo() class C { - [Interceptable] + public static void M(int lineNumber = 1) => throw null!; } @@ -3400,42 +3279,6 @@ class D verifier.VerifyDiagnostics(); } - [Fact] - public void InterceptableExplicitImplementation() - { - var source = """ - using System.Runtime.CompilerServices; - using System; - - var c = new C(); - ((I)c).M(); - - interface I - { - void M(); - } - - class C : I - { - [Interceptable] // 1 - void I.M() => throw null!; - } - - static class D - { - [InterceptsLocation("Program.cs", 5, 8)] - public static void Interceptor(this I i) => throw null!; - } - """; - - var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }); - comp.VerifyEmitDiagnostics( - // Program.cs(14,6): error CS27008: An interceptable method must be an ordinary member method. - // [Interceptable] // 1 - Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, "Interceptable").WithLocation(14, 6) - ); - } - [Fact] public void InterceptorExtern() { @@ -3446,7 +3289,7 @@ public void InterceptorExtern() class C { - [Interceptable] + public static void M() => throw null!; } @@ -3482,7 +3325,7 @@ public void InterceptorAbstract() abstract class C { - [Interceptable] + public void M() => throw null!; [InterceptsLocation("Program.cs", 5, 3)] @@ -3511,7 +3354,7 @@ public void InterceptorInterface() interface I { - [Interceptable] + public void M(); [InterceptsLocation("Program.cs", 5, 3)] diff --git a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs index d4ba2a87665f8..d0d00c09bf01f 100644 --- a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs +++ b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs @@ -304,7 +304,6 @@ public void WarningLevel_2() case ErrorCode.WRN_ParamsArrayInLambdaOnly: case ErrorCode.WRN_CapturedPrimaryConstructorParameterPassedToBase: case ErrorCode.WRN_UnreadPrimaryConstructorParameter: - case ErrorCode.WRN_CallNotInterceptable: case ErrorCode.WRN_InterceptorSignatureMismatch: case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnInterceptor: case ErrorCode.WRN_NullabilityMismatchInParameterTypeOnInterceptor: @@ -2941,7 +2940,6 @@ public void TestIsBuildOnlyDiagnostic() case ErrorCode.ERR_EncUpdateFailedDelegateTypeChanged: case ErrorCode.ERR_CannotBeConvertedToUtf8: case ErrorCode.ERR_FileTypeNonUniquePath: - case ErrorCode.WRN_CallNotInterceptable: case ErrorCode.ERR_InterceptorSignatureMismatch: case ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter: case ErrorCode.ERR_InterceptorMustNotHaveThisParameter: diff --git a/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs b/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs index 75a0010c53887..8e0d40e161b1c 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs @@ -69,19 +69,6 @@ internal static bool ContainsAllValues(int mask) where T : struct, Enum, ICon return true; } - internal static bool ContainsAllValues(long mask) where T : struct, Enum, IConvertible - { - foreach (T value in GetValues()) - { - long val = value.ToInt64(null); - if ((val & mask) != val) - { - return false; - } - } - return true; - } - internal static bool ContainsValue(T value) where T : struct, Enum { return Array.IndexOf(GetValues(), value) >= 0; diff --git a/src/Compilers/Core/Portable/InternalUtilities/ThreadSafeFlagOperations.cs b/src/Compilers/Core/Portable/InternalUtilities/ThreadSafeFlagOperations.cs index af304f9e051e5..536e48c2caba4 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/ThreadSafeFlagOperations.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/ThreadSafeFlagOperations.cs @@ -24,22 +24,6 @@ public static bool Set(ref int flags, int toSet) return true; } - public static bool Set(ref long flags, long toSet) - { - long oldState, newState; - do - { - oldState = flags; - newState = oldState | toSet; - if (newState == oldState) - { - return false; - } - } - while (Interlocked.CompareExchange(ref flags, newState, oldState) != oldState); - return true; - } - public static bool Clear(ref int flags, int toClear) { int oldState, newState; diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index 0e8c83d76fd2d..478a6c3f80911 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -1025,11 +1025,6 @@ internal bool HasFixedBufferAttribute(EntityHandle token, out string elementType return HasStringAndIntValuedAttribute(token, AttributeDescription.FixedBufferAttribute, out elementTypeName, out bufferSize); } - internal bool HasInterceptableAttribute(EntityHandle token) - { - return FindTargetAttribute(token, AttributeDescription.InterceptableAttribute).HasValue; - } - internal bool HasAccessedThroughPropertyAttribute(EntityHandle token, out string propertyName) { return HasStringValuedAttribute(token, AttributeDescription.AccessedThroughPropertyAttribute, out propertyName); diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs index b154a4e01d530..37002d0331598 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs @@ -387,7 +387,6 @@ static AttributeDescription() internal static readonly AttributeDescription StructLayoutAttribute = new AttributeDescription("System.Runtime.InteropServices", "StructLayoutAttribute", s_signaturesOfStructLayoutAttribute); internal static readonly AttributeDescription FieldOffsetAttribute = new AttributeDescription("System.Runtime.InteropServices", "FieldOffsetAttribute", s_signaturesOfFieldOffsetAttribute); internal static readonly AttributeDescription FixedBufferAttribute = new AttributeDescription("System.Runtime.CompilerServices", "FixedBufferAttribute", s_signaturesOfFixedBufferAttribute); - internal static readonly AttributeDescription InterceptableAttribute = new AttributeDescription("System.Runtime.CompilerServices", "InterceptableAttribute", s_signatures_HasThis_Void_Only); internal static readonly AttributeDescription InterceptsLocationAttribute = new AttributeDescription("System.Runtime.CompilerServices", "InterceptsLocationAttribute", s_signaturesOfInterceptsLocationAttribute); internal static readonly AttributeDescription AllowNullAttribute = new AttributeDescription("System.Diagnostics.CodeAnalysis", "AllowNullAttribute", s_signatures_HasThis_Void_Only); internal static readonly AttributeDescription DisallowNullAttribute = new AttributeDescription("System.Diagnostics.CodeAnalysis", "DisallowNullAttribute", s_signatures_HasThis_Void_Only); diff --git a/src/EditorFeatures/CSharp/LanguageServer/CSharpLspBuildOnlyDiagnostics.cs b/src/EditorFeatures/CSharp/LanguageServer/CSharpLspBuildOnlyDiagnostics.cs index bd2d532127a09..f9ea4475194f6 100644 --- a/src/EditorFeatures/CSharp/LanguageServer/CSharpLspBuildOnlyDiagnostics.cs +++ b/src/EditorFeatures/CSharp/LanguageServer/CSharpLspBuildOnlyDiagnostics.cs @@ -44,7 +44,6 @@ namespace Microsoft.CodeAnalysis.CSharp.LanguageServer "CS8984", // ErrorCode.ERR_EncUpdateFailedDelegateTypeChanged: "CS9026", // ErrorCode.ERR_CannotBeConvertedToUtf8: "CS9068", // ErrorCode.ERR_FileTypeNonUniquePath: - "CS27000", // ErrorCode.WRN_CallNotInterceptable: "CS27007", // ErrorCode.ERR_InterceptorSignatureMismatch "CS27011", // ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter "CS27012", // ErrorCode.ERR_InterceptorMustNotHaveThisParameter diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EECompilationContextMethod.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EECompilationContextMethod.cs index adf9b95a8d566..248c0d64c06a7 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EECompilationContextMethod.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EECompilationContextMethod.cs @@ -78,8 +78,6 @@ internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree l return _underlyingMethod.GetUnmanagedCallersOnlyAttributeData(forceComplete); } - internal override bool IsInterceptable => false; - internal override bool IsNullableAnalysisEnabled() { return _underlyingMethod.IsNullableAnalysisEnabled(); diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EEMethodSymbol.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EEMethodSymbol.cs index f5425d2141ad3..b2ad97f1b5419 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EEMethodSymbol.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EEMethodSymbol.cs @@ -451,8 +451,6 @@ public override bool IsExtern internal override bool IsInitOnly => false; - internal override bool IsInterceptable => false; - internal override ObsoleteAttributeData ObsoleteAttributeData { get { throw ExceptionUtilities.Unreachable(); } diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/PlaceholderMethodSymbol.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/PlaceholderMethodSymbol.cs index c3bc327c971c6..20372abe82bdd 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/PlaceholderMethodSymbol.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/PlaceholderMethodSymbol.cs @@ -277,8 +277,6 @@ internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree l internal override bool IsNullableAnalysisEnabled() => false; - internal override bool IsInterceptable => false; - protected override bool HasSetsRequiredMembersImpl => throw ExceptionUtilities.Unreachable(); #if DEBUG