diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ExtensionGroupingInfo.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ExtensionGroupingInfo.cs
index 8acf92b0a5d04..9d1f2c5224adb 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/ExtensionGroupingInfo.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/ExtensionGroupingInfo.cs
@@ -21,16 +21,13 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
internal sealed class ExtensionGroupingInfo
{
- ///
- /// Extension block symbols declared in a class are grouped by their corresponding grouping type metadata name (top level key),
- /// then grouped by their corresponding extension marker type metadata name (the secondary key used by MultiDictionary).
- /// s are the extension blocks.
- ///
- private readonly Dictionary> _groupingMap;
- private ImmutableArray _lazyGroupingTypes;
+ private readonly ImmutableArray _groupingTypes;
public ExtensionGroupingInfo(SourceMemberContainerTypeSymbol container)
{
+ // Extension block symbols declared in a class are grouped by their corresponding grouping type metadata name (top level key),
+ // then grouped by their corresponding extension marker type metadata name (the secondary key used by MultiDictionary).
+ // SourceNamedTypeSymbols are the extension blocks.
var groupingMap = new Dictionary>(EqualityComparer.Default);
foreach (var type in container.GetTypeMembers(""))
@@ -54,7 +51,16 @@ public ExtensionGroupingInfo(SourceMemberContainerTypeSymbol container)
markerMap.Add(sourceNamedType.ExtensionMarkerName, sourceNamedType);
}
- _groupingMap = groupingMap;
+ var builder = ArrayBuilder.GetInstance(groupingMap.Count);
+
+ foreach (KeyValuePair> pair in groupingMap)
+ {
+ builder.Add(new ExtensionGroupingType(pair.Key, pair.Value));
+ }
+
+ builder.Sort();
+
+ _groupingTypes = builder.ToImmutableAndFree();
AssertInvariants(container);
}
@@ -94,21 +100,7 @@ private void AssertInvariants(SourceMemberContainerTypeSymbol container)
public ImmutableArray GetGroupingTypes()
{
- if (_lazyGroupingTypes.IsDefault)
- {
- var builder = ArrayBuilder.GetInstance(_groupingMap.Count);
-
- foreach (KeyValuePair> pair in _groupingMap)
- {
- builder.Add(new ExtensionGroupingType(pair.Key, pair.Value));
- }
-
- builder.Sort();
-
- ImmutableInterlocked.InterlockedInitialize(ref _lazyGroupingTypes, builder.ToImmutableAndFree());
- }
-
- return ImmutableArray.CastUp(_lazyGroupingTypes);
+ return ImmutableArray.CastUp(_groupingTypes);
}
public Cci.ITypeDefinition GetCorrespondingMarkerType(SynthesizedExtensionMarker markerMethod)
@@ -119,13 +111,12 @@ public Cci.ITypeDefinition GetCorrespondingMarkerType(SynthesizedExtensionMarker
private ExtensionMarkerType GetCorrespondingMarkerType(SourceNamedTypeSymbol extension)
{
Debug.Assert(extension.IsExtension);
- GetGroupingTypes();
// Tracked by https://github.com/dotnet/roslyn/issues/78827 : Optimize lookup with side dictionaries?
var groupingName = extension.ExtensionGroupingName;
var markerName = extension.ExtensionMarkerName;
- foreach (var groupingType in _lazyGroupingTypes)
+ foreach (var groupingType in _groupingTypes)
{
if (groupingType.Name != groupingName)
{
@@ -180,12 +171,11 @@ public Cci.TypeMemberVisibility GetCorrespondingMarkerMethodVisibility(Synthesiz
public Cci.ITypeDefinition GetCorrespondingGroupingType(SourceNamedTypeSymbol extension)
{
Debug.Assert(extension.IsExtension);
- GetGroupingTypes();
// Tracked by https://github.com/dotnet/roslyn/issues/78827 : Optimize lookup with a side dictionary?
var groupingName = extension.ExtensionGroupingName;
- foreach (var groupingType in _lazyGroupingTypes)
+ foreach (var groupingType in _groupingTypes)
{
if (groupingType.Name == groupingName)
{
@@ -210,8 +200,7 @@ internal ImmutableArray GetMergedExtensions(SourceNamedTy
///
internal IEnumerable> EnumerateMergedExtensionBlocks()
{
- GetGroupingTypes();
- foreach (var groupingType in _lazyGroupingTypes)
+ foreach (var groupingType in _groupingTypes)
{
foreach (var markerType in groupingType.ExtensionMarkerTypes)
{
@@ -436,10 +425,9 @@ static void substituteConstraintTypes(ImmutableArray types,
///
internal void CheckSignatureCollisions(BindingDiagnosticBag diagnostics)
{
- GetGroupingTypes();
PooledHashSet? alreadyReportedExtensions = null;
- foreach (ExtensionGroupingType groupingType in _lazyGroupingTypes)
+ foreach (ExtensionGroupingType groupingType in _groupingTypes)
{
checkCollisions(enumerateExtensionsInGrouping(groupingType), HaveSameILSignature, ref alreadyReportedExtensions, diagnostics);
}
@@ -691,7 +679,7 @@ private sealed class ExtensionGroupingType : ExtensionGroupingOrMarkerType, ICom
{
private readonly string _name;
public readonly ImmutableArray ExtensionMarkerTypes;
- private readonly ImmutableArray _typeParameters;
+ private ImmutableArray _lazyTypeParameters;
public ExtensionGroupingType(string name, MultiDictionary extensionMarkerTypes)
{
@@ -706,10 +694,6 @@ public ExtensionGroupingType(string name, MultiDictionary new ExtensionGroupingTypeTypeParameter(@this, p), this) :
- [];
}
int IComparable.CompareTo(ExtensionGroupingType? other)
@@ -718,7 +702,21 @@ int IComparable.CompareTo(ExtensionGroupingType? other)
return ExtensionMarkerTypes[0].CompareTo(other.ExtensionMarkerTypes[0]);
}
- protected override IEnumerable GenericParameters => _typeParameters;
+ protected override IEnumerable GenericParameters
+ {
+ get
+ {
+ if (_lazyTypeParameters.IsDefault)
+ {
+ var typeParameters = ExtensionMarkerTypes[0].UnderlyingExtensions[0].Arity != 0 ?
+ ((INestedTypeDefinition)ExtensionMarkerTypes[0].UnderlyingExtensions[0].GetCciAdapter()).GenericParameters.SelectAsArray(static (p, @this) => new ExtensionGroupingTypeTypeParameter(@this, p), this) :
+ [];
+ ImmutableInterlocked.InterlockedInitialize(ref _lazyTypeParameters, typeParameters);
+ }
+
+ return _lazyTypeParameters;
+ }
+ }
protected override ushort GenericParameterCount => (ushort)ExtensionMarkerTypes[0].UnderlyingExtensions[0].Arity;
@@ -841,7 +839,7 @@ private sealed class ExtensionMarkerType : ExtensionGroupingOrMarkerType, ICompa
public readonly ExtensionGroupingType GroupingType;
private readonly string _name;
public readonly ImmutableArray UnderlyingExtensions;
- private readonly ImmutableArray _typeParameters;
+ private ImmutableArray _lazyTypeParameters;
public ExtensionMarkerType(ExtensionGroupingType groupingType, string name, MultiDictionary.ValueSet extensions)
{
@@ -852,10 +850,6 @@ public ExtensionMarkerType(ExtensionGroupingType groupingType, string name, Mult
builder.AddRange(extensions);
builder.Sort(LexicalOrderSymbolComparer.Instance);
UnderlyingExtensions = builder.ToImmutableAndFree();
-
- _typeParameters = UnderlyingExtensions[0].Arity != 0 ?
- ((INestedTypeDefinition)UnderlyingExtensions[0].GetCciAdapter()).GenericParameters.SelectAsArray(static (p, @this) => new InheritedTypeParameter(p.Index, @this, p), this) :
- [];
}
public int CompareTo(ExtensionMarkerType? other)
@@ -864,7 +858,21 @@ public int CompareTo(ExtensionMarkerType? other)
return LexicalOrderSymbolComparer.Instance.Compare(UnderlyingExtensions[0], other.UnderlyingExtensions[0]);
}
- protected override IEnumerable GenericParameters => _typeParameters;
+ protected override IEnumerable GenericParameters
+ {
+ get
+ {
+ if (_lazyTypeParameters.IsDefault)
+ {
+ var typeParameters = UnderlyingExtensions[0].Arity != 0 ?
+ ((INestedTypeDefinition)UnderlyingExtensions[0].GetCciAdapter()).GenericParameters.SelectAsArray(static (p, @this) => new InheritedTypeParameter(p.Index, @this, p), this) :
+ [];
+ ImmutableInterlocked.InterlockedInitialize(ref _lazyTypeParameters, typeParameters);
+ }
+
+ return _lazyTypeParameters;
+ }
+ }
protected override ushort GenericParameterCount => (ushort)UnderlyingExtensions[0].Arity;