Skip to content

Commit b62e77a

Browse files
author
Julien Couvreur
committed
Extensions: add Name property on embedded ExtensionMarkerAttribute
1 parent 1d67ba7 commit b62e77a

File tree

4 files changed

+543
-273
lines changed

4 files changed

+543
-273
lines changed

src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEmbeddedExtensionMarkerNameAttributeSymbol.cs

Lines changed: 177 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,23 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections.Generic;
67
using System.Collections.Immutable;
78
using System.Diagnostics;
9+
using System.Reflection;
10+
using Microsoft.Cci;
11+
using Microsoft.CodeAnalysis.PooledObjects;
812

913
namespace Microsoft.CodeAnalysis.CSharp.Symbols
1014
{
11-
// Tracked by https://github.com/dotnet/roslyn/issues/78963 : We are not declaring and not initializing the "Name" property yet.
1215
internal sealed class SynthesizedEmbeddedExtensionMarkerAttributeSymbol : SynthesizedEmbeddedAttributeSymbolBase
1316
{
1417
private readonly ImmutableArray<MethodSymbol> _constructors;
18+
private readonly SynthesizedFieldSymbol _nameField;
19+
private readonly NamePropertySymbol _nameProperty;
20+
21+
private const string PropertyName = "Name";
22+
private const string FieldName = "<Name>k__BackingField";
1523

1624
public SynthesizedEmbeddedExtensionMarkerAttributeSymbol(
1725
string name,
@@ -21,10 +29,11 @@ public SynthesizedEmbeddedExtensionMarkerAttributeSymbol(
2129
TypeSymbol systemStringType)
2230
: base(name, containingNamespace, containingModule, baseType: systemAttributeType)
2331
{
24-
_constructors = ImmutableArray.Create<MethodSymbol>(
25-
new SynthesizedEmbeddedAttributeConstructorSymbol(
26-
this,
27-
m => ImmutableArray.Create(SynthesizedParameterSymbol.Create(m, TypeWithAnnotations.Create(systemStringType), 0, RefKind.None, name: "name"))));
32+
Debug.Assert(FieldName == GeneratedNames.MakeBackingFieldName(PropertyName));
33+
34+
_nameField = new SynthesizedFieldSymbol(this, systemStringType, FieldName);
35+
_nameProperty = new NamePropertySymbol(_nameField);
36+
_constructors = [new ConstructorSymbol(this, systemStringType, _nameField)];
2837

2938
// Ensure we never get out of sync with the description
3039
Debug.Assert(_constructors.Length == AttributeDescription.ExtensionMarkerAttribute.Signatures.Length);
@@ -39,5 +48,168 @@ internal override AttributeUsageInfo GetAttributeUsageInfo()
3948
AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate,
4049
allowMultiple: false, inherited: false);
4150
}
51+
52+
internal override IEnumerable<FieldSymbol> GetFieldsToEmit()
53+
{
54+
return [_nameField];
55+
}
56+
57+
public override ImmutableArray<Symbol> GetMembers()
58+
=> [_nameField, _nameProperty, _nameProperty.GetMethod, _constructors[0]];
59+
60+
public override ImmutableArray<Symbol> GetMembers(string name)
61+
{
62+
return name switch
63+
{
64+
FieldName => [_nameField],
65+
PropertyName => [_nameProperty],
66+
WellKnownMemberNames.InstanceConstructorName => [_constructors[0]],
67+
_ => []
68+
};
69+
}
70+
71+
public override IEnumerable<string> MemberNames
72+
=> [_nameField.Name, PropertyName, WellKnownMemberNames.InstanceConstructorName];
73+
74+
private sealed class ConstructorSymbol : SynthesizedInstanceConstructor
75+
{
76+
private readonly ImmutableArray<ParameterSymbol> _parameters;
77+
private readonly SynthesizedFieldSymbol _nameField;
78+
79+
internal ConstructorSymbol(
80+
NamedTypeSymbol containingType,
81+
TypeSymbol systemStringType,
82+
SynthesizedFieldSymbol nameField) :
83+
base(containingType)
84+
{
85+
_parameters = [SynthesizedParameterSymbol.Create(containingType, TypeWithAnnotations.Create(systemStringType), ordinal: 0, RefKind.None, name: "name")];
86+
_nameField = nameField;
87+
}
88+
89+
public override ImmutableArray<ParameterSymbol> Parameters => _parameters;
90+
91+
internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
92+
{
93+
GenerateMethodBodyCore(compilationState, diagnostics);
94+
}
95+
96+
internal override void GenerateMethodBodyStatements(SyntheticBoundNodeFactory f, ArrayBuilder<BoundStatement> statements, BindingDiagnosticBag diagnostics)
97+
{
98+
// this._namedField = name;
99+
statements.Add(f.Assignment(f.Field(f.This(), _nameField), f.Parameter(_parameters[0])));
100+
}
101+
}
102+
103+
private sealed class NamePropertySymbol : PropertySymbol
104+
{
105+
private readonly SynthesizedFieldSymbol _backingField;
106+
107+
public NamePropertySymbol(SynthesizedFieldSymbol backingField)
108+
{
109+
_backingField = backingField;
110+
GetMethod = new NameGetAccessorMethodSymbol(this, backingField);
111+
}
112+
113+
public override string Name => PropertyName;
114+
public override TypeWithAnnotations TypeWithAnnotations => _backingField.TypeWithAnnotations;
115+
public override RefKind RefKind => RefKind.None;
116+
public override ImmutableArray<CustomModifier> RefCustomModifiers => [];
117+
public override MethodSymbol GetMethod { get; }
118+
public override MethodSymbol? SetMethod => null;
119+
public override Symbol ContainingSymbol => _backingField.ContainingSymbol;
120+
public override Accessibility DeclaredAccessibility => Accessibility.Internal;
121+
122+
public override ImmutableArray<Location> Locations => [];
123+
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences => [];
124+
public override ImmutableArray<PropertySymbol> ExplicitInterfaceImplementations => [];
125+
public override ImmutableArray<ParameterSymbol> Parameters => [];
126+
public override bool IsIndexer => false;
127+
public override bool IsStatic => false;
128+
public override bool IsVirtual => false;
129+
public override bool IsOverride => false;
130+
public override bool IsAbstract => false;
131+
public override bool IsSealed => false;
132+
public override bool IsExtern => false;
133+
internal override bool IsRequired => false;
134+
internal override bool HasSpecialName => false;
135+
internal override CallingConvention CallingConvention => CallingConvention.HasThis;
136+
internal override bool MustCallMethodsDirectly => false;
137+
internal override bool HasUnscopedRefAttribute => false;
138+
internal override ObsoleteAttributeData? ObsoleteAttributeData => null;
139+
internal override int TryGetOverloadResolutionPriority() => 0;
140+
}
141+
142+
private sealed partial class NameGetAccessorMethodSymbol : SynthesizedMethodSymbol
143+
{
144+
private readonly NamePropertySymbol _nameProperty;
145+
private readonly SynthesizedFieldSymbol _backingField;
146+
147+
public NameGetAccessorMethodSymbol(NamePropertySymbol nameProperty, SynthesizedFieldSymbol backingField)
148+
{
149+
_nameProperty = nameProperty;
150+
_backingField = backingField;
151+
}
152+
153+
public override string Name => "get_Name";
154+
internal override bool HasSpecialName => true;
155+
public override MethodKind MethodKind => MethodKind.PropertyGet;
156+
public override Symbol AssociatedSymbol => _nameProperty;
157+
public override Symbol ContainingSymbol => _nameProperty.ContainingSymbol;
158+
159+
internal override bool SynthesizesLoweredBoundBody => true;
160+
161+
internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
162+
{
163+
SyntheticBoundNodeFactory F = new SyntheticBoundNodeFactory(this, this.GetNonNullSyntaxNode(), compilationState, diagnostics);
164+
F.CurrentFunction = this.OriginalDefinition;
165+
166+
try
167+
{
168+
// return this._backingField;
169+
F.CloseMethod(F.Return(F.Field(F.This(), _backingField)));
170+
}
171+
catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
172+
{
173+
diagnostics.Add(ex.Diagnostic);
174+
}
175+
}
176+
177+
public override bool IsStatic => false;
178+
public override int Arity => 0;
179+
public override bool IsExtensionMethod => false;
180+
public override bool HidesBaseMethodsByName => false;
181+
public override bool IsVararg => false;
182+
public override bool ReturnsVoid => false;
183+
public override bool IsAsync => false;
184+
public override RefKind RefKind => RefKind.None;
185+
public override ImmutableArray<CustomModifier> RefCustomModifiers => [];
186+
public override TypeWithAnnotations ReturnTypeWithAnnotations => _nameProperty.TypeWithAnnotations;
187+
public override FlowAnalysisAnnotations ReturnTypeFlowAnalysisAnnotations => FlowAnalysisAnnotations.None;
188+
public override ImmutableHashSet<string> ReturnNotNullIfParameterNotNull => [];
189+
public override ImmutableArray<TypeWithAnnotations> TypeArgumentsWithAnnotations => [];
190+
public override ImmutableArray<TypeParameterSymbol> TypeParameters => [];
191+
public override ImmutableArray<ParameterSymbol> Parameters => [];
192+
public override ImmutableArray<MethodSymbol> ExplicitInterfaceImplementations => [];
193+
public override ImmutableArray<Location> Locations => [];
194+
public override Accessibility DeclaredAccessibility => Accessibility.Internal;
195+
public override bool IsVirtual => false;
196+
public override bool IsOverride => false;
197+
public override bool IsAbstract => false;
198+
public override bool IsSealed => false;
199+
public override bool IsExtern => false;
200+
protected override bool HasSetsRequiredMembersImpl => false;
201+
internal override MethodImplAttributes ImplementationAttributes => default;
202+
internal override bool HasDeclarativeSecurity => false;
203+
internal override MarshalPseudoCustomAttributeData? ReturnValueMarshallingInformation => null;
204+
internal override bool RequiresSecurityObject => false;
205+
internal override CallingConvention CallingConvention => CallingConvention.HasThis;
206+
internal override bool GenerateDebugInfo => false;
207+
208+
public override DllImportData? GetDllImportData() => null;
209+
internal override ImmutableArray<string> GetAppliedConditionalSymbols() => [];
210+
internal override IEnumerable<SecurityAttribute>? GetSecurityInformation() => null;
211+
internal override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false) => false;
212+
internal override bool IsMetadataVirtual(IsMetadataVirtualOption option = IsMetadataVirtualOption.None) => false;
213+
}
42214
}
43215
}

0 commit comments

Comments
 (0)