Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,13 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
internal sealed class ExtensionGroupingInfo
{
/// <summary>
/// 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).
/// <see cref="SourceNamedTypeSymbol"/>s are the extension blocks.
/// </summary>
private readonly Dictionary<string, MultiDictionary<string, SourceNamedTypeSymbol>> _groupingMap;
private ImmutableArray<ExtensionGroupingType> _lazyGroupingTypes;
private readonly ImmutableArray<ExtensionGroupingType> _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<string, MultiDictionary<string, SourceNamedTypeSymbol>>(EqualityComparer<string>.Default);

foreach (var type in container.GetTypeMembers(""))
Expand All @@ -54,7 +51,16 @@ public ExtensionGroupingInfo(SourceMemberContainerTypeSymbol container)
markerMap.Add(sourceNamedType.ExtensionMarkerName, sourceNamedType);
}

_groupingMap = groupingMap;
var builder = ArrayBuilder<ExtensionGroupingType>.GetInstance(groupingMap.Count);

foreach (KeyValuePair<string, MultiDictionary<string, SourceNamedTypeSymbol>> pair in groupingMap)
{
builder.Add(new ExtensionGroupingType(pair.Key, pair.Value));
}

builder.Sort();

_groupingTypes = builder.ToImmutableAndFree();
AssertInvariants(container);
}

Expand Down Expand Up @@ -94,21 +100,7 @@ private void AssertInvariants(SourceMemberContainerTypeSymbol container)

public ImmutableArray<Cci.INestedTypeDefinition> GetGroupingTypes()
{
if (_lazyGroupingTypes.IsDefault)
{
var builder = ArrayBuilder<ExtensionGroupingType>.GetInstance(_groupingMap.Count);

foreach (KeyValuePair<string, MultiDictionary<string, SourceNamedTypeSymbol>> pair in _groupingMap)
{
builder.Add(new ExtensionGroupingType(pair.Key, pair.Value));
}

builder.Sort();

ImmutableInterlocked.InterlockedInitialize(ref _lazyGroupingTypes, builder.ToImmutableAndFree());
}

return ImmutableArray<Cci.INestedTypeDefinition>.CastUp(_lazyGroupingTypes);
return ImmutableArray<Cci.INestedTypeDefinition>.CastUp(_groupingTypes);
}

public Cci.ITypeDefinition GetCorrespondingMarkerType(SynthesizedExtensionMarker markerMethod)
Expand All @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand All @@ -210,8 +200,7 @@ internal ImmutableArray<SourceNamedTypeSymbol> GetMergedExtensions(SourceNamedTy
/// </summary>
internal IEnumerable<ImmutableArray<SourceNamedTypeSymbol>> EnumerateMergedExtensionBlocks()
{
GetGroupingTypes();
foreach (var groupingType in _lazyGroupingTypes)
foreach (var groupingType in _groupingTypes)
{
foreach (var markerType in groupingType.ExtensionMarkerTypes)
{
Expand Down Expand Up @@ -436,10 +425,9 @@ static void substituteConstraintTypes(ImmutableArray<TypeWithAnnotations> types,
/// </summary>
internal void CheckSignatureCollisions(BindingDiagnosticBag diagnostics)
{
GetGroupingTypes();
PooledHashSet<SourceNamedTypeSymbol>? alreadyReportedExtensions = null;

foreach (ExtensionGroupingType groupingType in _lazyGroupingTypes)
foreach (ExtensionGroupingType groupingType in _groupingTypes)
{
checkCollisions(enumerateExtensionsInGrouping(groupingType), HaveSameILSignature, ref alreadyReportedExtensions, diagnostics);
}
Expand Down Expand Up @@ -691,7 +679,7 @@ private sealed class ExtensionGroupingType : ExtensionGroupingOrMarkerType, ICom
{
private readonly string _name;
public readonly ImmutableArray<ExtensionMarkerType> ExtensionMarkerTypes;
private readonly ImmutableArray<ExtensionGroupingTypeTypeParameter> _typeParameters;
private ImmutableArray<ExtensionGroupingTypeTypeParameter> _lazyTypeParameters;

public ExtensionGroupingType(string name, MultiDictionary<string, SourceNamedTypeSymbol> extensionMarkerTypes)
{
Expand All @@ -706,10 +694,6 @@ public ExtensionGroupingType(string name, MultiDictionary<string, SourceNamedTyp

builder.Sort();
ExtensionMarkerTypes = builder.ToImmutableAndFree();

_typeParameters = ExtensionMarkerTypes[0].UnderlyingExtensions[0].Arity != 0 ?
((INestedTypeDefinition)ExtensionMarkerTypes[0].UnderlyingExtensions[0].GetCciAdapter()).GenericParameters.SelectAsArray(static (p, @this) => new ExtensionGroupingTypeTypeParameter(@this, p), this) :
[];
}

int IComparable<ExtensionGroupingType>.CompareTo(ExtensionGroupingType? other)
Expand All @@ -718,7 +702,21 @@ int IComparable<ExtensionGroupingType>.CompareTo(ExtensionGroupingType? other)
return ExtensionMarkerTypes[0].CompareTo(other.ExtensionMarkerTypes[0]);
}

protected override IEnumerable<IGenericTypeParameter> GenericParameters => _typeParameters;
protected override IEnumerable<IGenericTypeParameter> 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;

Expand Down Expand Up @@ -841,7 +839,7 @@ private sealed class ExtensionMarkerType : ExtensionGroupingOrMarkerType, ICompa
public readonly ExtensionGroupingType GroupingType;
private readonly string _name;
public readonly ImmutableArray<SourceNamedTypeSymbol> UnderlyingExtensions;
private readonly ImmutableArray<InheritedTypeParameter> _typeParameters;
private ImmutableArray<InheritedTypeParameter> _lazyTypeParameters;

public ExtensionMarkerType(ExtensionGroupingType groupingType, string name, MultiDictionary<string, SourceNamedTypeSymbol>.ValueSet extensions)
{
Expand All @@ -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)
Expand All @@ -864,7 +858,21 @@ public int CompareTo(ExtensionMarkerType? other)
return LexicalOrderSymbolComparer.Instance.Compare(UnderlyingExtensions[0], other.UnderlyingExtensions[0]);
}

protected override IEnumerable<IGenericTypeParameter> GenericParameters => _typeParameters;
protected override IEnumerable<IGenericTypeParameter> 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;

Expand Down