Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Compilers/CSharp/Portable/Symbols/ErrorMethodSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ internal sealed override ObsoleteAttributeData ObsoleteAttributeData

internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => null;

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

public override Accessibility DeclaredAccessibility
{
get { return Accessibility.Public; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ internal sealed override int CalculateLocalSyntaxOffset(int localPosition, Synta
internal sealed override UnmanagedCallersOnlyAttributeData? GetUnmanagedCallersOnlyAttributeData(bool forceComplete)
=> _originalMethod.GetUnmanagedCallersOnlyAttributeData(forceComplete);

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

public sealed override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return _typeMap.SubstituteCustomModifiers(_originalMethod.RefCustomModifiers); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public SourceExtensionImplementationMethodSymbol(MethodSymbol sourceMethod)
public override MethodKind MethodKind => MethodKind.Ordinary;
public override bool IsImplicitlyDeclared => true;

internal override bool HasSpecialName => false;
internal override bool HasSpecialName => _originalMethod.HasSpecialNameAttribute;

internal override int ParameterCount
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,7 @@ public override bool IsVararg
internal override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false) => false;
internal override bool IsMetadataVirtual(IsMetadataVirtualOption option = IsMetadataVirtualOption.None) => false;
internal sealed override UnmanagedCallersOnlyAttributeData? GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => null;
internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override bool GenerateDebugInfo => throw ExceptionUtilities.Unreachable();
internal override ObsoleteAttributeData? ObsoleteAttributeData => throw ExceptionUtilities.Unreachable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,8 @@ internal override ObsoleteAttributeData ObsoleteAttributeData

return _uncommonFields?._lazyUnmanagedCallersOnlyAttributeData;
}

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();
#nullable disable

internal override bool GenerateDebugInfo => false;
Expand Down
2 changes: 2 additions & 0 deletions src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ public virtual bool IsGenericMethod
/// </summary>
internal virtual bool IsDirectlyExcludedFromCodeCoverage { get => false; }

internal abstract bool HasSpecialNameAttribute { get; }

/// <summary>
/// If a method is annotated with `[MemberNotNull(...)]` attributes, returns the list of members
/// listed in those attributes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ public override ImmutableArray<ParameterSymbol> Parameters

internal override UnmanagedCallersOnlyAttributeData? GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => UnderlyingMethod.GetUnmanagedCallersOnlyAttributeData(forceComplete);

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

public override Symbol? AssociatedSymbol => _associatedSymbol;

internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ internal sealed override ObsoleteAttributeData ObsoleteAttributeData
internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete)
=> _reducedFrom.GetUnmanagedCallersOnlyAttributeData(forceComplete);

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

public override Accessibility DeclaredAccessibility
{
get { return _reducedFrom.DeclaredAccessibility; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ public override ImmutableArray<CSharpAttributeData> GetReturnTypeAttributes()
return _lazyUnmanagedAttributeData;
}

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override bool TryGetThisParameter(out ParameterSymbol? thisParameter)
{
if (!_underlyingMethod.TryGetThisParameter(out var underlyingParameter))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ internal sealed override bool HasAsyncMethodBuilderAttribute(out TypeSymbol buil

internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => throw ExceptionUtilities.Unreachable();

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override ImmutableArray<string> GetAppliedConditionalSymbols() { throw ExceptionUtilities.Unreachable(); }

public override ImmutableArray<TypeWithAnnotations> TypeArgumentsWithAnnotations { get { throw ExceptionUtilities.Unreachable(); } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#nullable disable

using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
Expand Down Expand Up @@ -1677,11 +1676,13 @@ internal override bool HasSpecialName
return true;
}

var data = GetDecodedWellKnownAttributeData();
return data != null && data.HasSpecialNameAttribute;
return HasSpecialNameAttribute;
}
}

internal sealed override bool HasSpecialNameAttribute =>
GetDecodedWellKnownAttributeData()?.HasSpecialNameAttribute == true;

internal sealed override bool IsDirectlyExcludedFromCodeCoverage =>
GetDecodedWellKnownAttributeData()?.HasExcludeFromCodeCoverageAttribute == true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ public override ImmutableArray<CSharpAttributeData> GetReturnTypeAttributes()
internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete)
=> this.OriginalDefinition.GetUnmanagedCallersOnlyAttributeData(forceComplete);

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

public sealed override Symbol AssociatedSymbol
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ internal sealed override ObsoleteAttributeData ObsoleteAttributeData

internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => null;

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override Cci.CallingConvention CallingConvention
{
get { return 0; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ internal sealed override ObsoleteAttributeData ObsoleteAttributeData

internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => null;

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal sealed override ImmutableArray<string> GetAppliedConditionalSymbols()
{
return ImmutableArray<string>.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ internal override ObsoleteAttributeData ObsoleteAttributeData

internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => null;

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree)
{
throw ExceptionUtilities.Unreachable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ internal sealed override ObsoleteAttributeData ObsoleteAttributeData

internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => null;

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree)
{
throw ExceptionUtilities.Unreachable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ internal sealed override ObsoleteAttributeData? ObsoleteAttributeData

internal sealed override UnmanagedCallersOnlyAttributeData? GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => null;

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override ImmutableArray<string> GetAppliedConditionalSymbols()
{
return ImmutableArray<string>.Empty;
Expand Down
103 changes: 89 additions & 14 deletions src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,7 @@ public static class Extensions

VerifyTypeIL(verifier, "Extensions", """
.class public auto ansi abstract sealed beforefieldinit Extensions
extends [netstandard]System.Object
extends [netstandard]System.Object
{
.custom instance void [netstandard]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = (
01 00 00 00
Expand All @@ -2132,10 +2132,10 @@ .class nested public auto ansi sealed specialname beforefieldinit '<>E__0'
extends [netstandard]System.Object
{
// Methods
.method private hidebysig specialname static
.method private hidebysig specialname static
void '<Extension>$' (
object ''
) cil managed
) cil managed
{
.custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
Expand All @@ -2145,19 +2145,19 @@ 01 00 00 00
.maxstack 8
IL_0000: ret
} // end of method '<>E__0'::'<Extension>$'
.method private hidebysig specialname static
int32 get_Property () cil managed
.method private hidebysig specialname static
int32 get_Property () cil managed
{
// Method begins at RVA 0x206d
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldnull
IL_0001: throw
} // end of method '<>E__0'::get_Property
.method private hidebysig specialname static
.method private hidebysig specialname static
void set_Property (
int32 'value'
) cil managed
) cil managed
{
// Method begins at RVA 0x206d
// Code size 2 (0x2)
Expand All @@ -2174,7 +2174,7 @@ .property int32 Property()
} // end of class <>E__0
// Methods
.method private hidebysig static
int32 get_Property () cil managed
int32 get_Property () cil managed
{
// Method begins at RVA 0x2067
// Code size 3 (0x3)
Expand All @@ -2185,7 +2185,7 @@ .maxstack 8
.method private hidebysig static
void set_Property (
int32 'value'
) cil managed
) cil managed
{
// Method begins at RVA 0x206b
// Code size 1 (0x1)
Expand Down Expand Up @@ -9953,10 +9953,10 @@ .class nested public auto ansi sealed specialname beforefieldinit '<>E__0'
extends [mscorlib]System.Object
{
// Methods
.method private hidebysig specialname static
.method private hidebysig specialname static
void '<Extension>$' (
object o
) cil managed
) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
Expand All @@ -9966,8 +9966,8 @@ 01 00 00 00
.maxstack 8
IL_0000: ret
} // end of method '<>E__0'::'<Extension>$'
.method public hidebysig specialname
instance string get_P () cil managed
.method public hidebysig specialname
instance string get_P () cil managed
{
// Method begins at RVA 0x2071
// Code size 2 (0x2)
Expand All @@ -9985,7 +9985,7 @@ .property instance string P()
.method public hidebysig static
string get_P (
object o
) cil managed
) cil managed
{
// Method begins at RVA 0x2067
// Code size 7 (0x7)
Expand Down Expand Up @@ -41115,6 +41115,81 @@ .method public hidebysig static void M () cil managed
Assert.False(comp.GlobalNamespace.GetTypeMember("E").GetTypeMembers().Single().IsExtension);
}

[Fact]
public void SpecialName_04()
{
var src = """
static class E
{
extension(int i)
{
[System.Runtime.CompilerServices.SpecialName]
public void M() => throw null!;

public void M2() => throw null!;

[System.Runtime.CompilerServices.SpecialName]
public int P => throw null!;

public int P2 => throw null!;
}

[System.Runtime.CompilerServices.SpecialName]
public static void M3() => throw null!;
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics();

var extension = comp.GlobalNamespace.GetTypeMember("E").GetTypeMembers().Single();
Assert.True(extension.GetMember<MethodSymbol>("M").HasSpecialName);
Assert.False(extension.GetMember<MethodSymbol>("M2").HasSpecialName);

Assert.True(extension.GetMember<PropertySymbol>("P").HasSpecialName);
Assert.True(extension.GetMember<MethodSymbol>("get_P").HasSpecialName);

Assert.False(extension.GetMember<PropertySymbol>("P2").HasSpecialName);
Assert.True(extension.GetMember<MethodSymbol>("get_P2").HasSpecialName);

Assert.True(comp.GetMember<MethodSymbol>("E.M").HasSpecialName);
Assert.False(comp.GetMember<MethodSymbol>("E.M2").HasSpecialName);
Assert.True(comp.GetMember<MethodSymbol>("E.M3").HasSpecialName);

Assert.False(comp.GetMember<MethodSymbol>("E.get_P").HasSpecialName);

Assert.False(comp.GetMember<MethodSymbol>("E.get_P2").HasSpecialName);
}

[Fact]
public void SpecialName_05()
{
var src = """
static class E
{
extension(int i)
{
public int P
{
[System.Runtime.CompilerServices.SpecialName]
get => 0;
[System.Runtime.CompilerServices.SpecialName]
set { }
}
}
}
""";
var comp = CreateCompilation(src);
comp.VerifyEmitDiagnostics();

var extension = comp.GlobalNamespace.GetTypeMember("E").GetTypeMembers().Single();
Assert.False(extension.GetMember<PropertySymbol>("P").HasSpecialName);
Assert.True(extension.GetMember<MethodSymbol>("get_P").HasSpecialName);
Assert.True(extension.GetMember<MethodSymbol>("set_P").HasSpecialName);

Assert.True(comp.GetMember<MethodSymbol>("E.get_P").HasSpecialName);
Assert.True(comp.GetMember<MethodSymbol>("E.set_P").HasSpecialName);
}

[Fact]
public void WellKnownAttribute_SkipLocalsInit_01()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree l
return _underlyingMethod.GetUnmanagedCallersOnlyAttributeData(forceComplete);
}

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override bool IsNullableAnalysisEnabled()
{
return _underlyingMethod.IsNullableAnalysisEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ internal override ObsoleteAttributeData ObsoleteAttributeData

internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => throw ExceptionUtilities.Unreachable();

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override bool HasUnscopedRefAttribute => false;

internal override bool UseUpdatedEscapeRules => false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ internal override ObsoleteAttributeData ObsoleteAttributeData

internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete) => throw ExceptionUtilities.Unreachable();

internal sealed override bool HasSpecialNameAttribute => throw ExceptionUtilities.Unreachable();

internal override bool HasUnscopedRefAttribute => false;

internal override bool UseUpdatedEscapeRules => false;
Expand Down
Loading