Skip to content

Commit

Permalink
Remove Lookup impl and use MultiValueDict
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-strecker-sonarsource committed May 3, 2022
1 parent f30f670 commit 7e4c15f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,25 +116,25 @@ private static void ReportRedundantInterfaces(SyntaxNodeAnalysisContext context,
}
}

private static ILookup<INamedTypeSymbol, INamedTypeSymbol> GetImplementedInterfaceMappings(BaseListSyntax baseList, SemanticModel semanticModel) =>
private static MultiValueDictionary<INamedTypeSymbol, INamedTypeSymbol> GetImplementedInterfaceMappings(BaseListSyntax baseList, SemanticModel semanticModel) =>
baseList.Types
.Select(baseType => semanticModel.GetSymbolInfo(baseType.Type).Symbol as INamedTypeSymbol)
.WhereNotNull()
.Distinct()
.ToLookup(x => x.AllInterfaces.AsEnumerable());
.ToMultiValueDictionary(x => x.AllInterfaces);

private static INamedTypeSymbol CollidingDeclaration(INamedTypeSymbol declaredType,
INamedTypeSymbol interfaceType,
ILookup<INamedTypeSymbol, INamedTypeSymbol> interfaceMappings)
MultiValueDictionary<INamedTypeSymbol, INamedTypeSymbol> interfaceMappings)
{
var collisionMapping = interfaceMappings.FirstOrDefault(x => x.Key.IsInterface() && x.Contains(interfaceType));
if (collisionMapping?.Key is not null)
var collisionMapping = interfaceMappings.FirstOrDefault(x => x.Key.IsInterface() && x.Value.Contains(interfaceType));
if (collisionMapping.Key is not null)
{
return collisionMapping.Key;
}

var baseClassMapping = interfaceMappings.FirstOrDefault(x => x.Key.IsClass());
if (baseClassMapping?.Key is null)
if (baseClassMapping.Key is null)
{
return null;
}
Expand Down
68 changes: 6 additions & 62 deletions analyzers/src/SonarAnalyzer.Common/Common/MultiValueDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,12 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont

public static class MultiValueDictionaryExtensions
{
public static MultiValueDictionary<TKey, TElement> ToMultiValueDictionary<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, ICollection<TElement>> elementSelector)
public static MultiValueDictionary<TSource, TElement> ToMultiValueDictionary<TSource, TElement>(this IEnumerable<TSource> source, Func<TSource, ICollection<TElement>> elementSelector) =>
source.ToMultiValueDictionary(x => x, elementSelector);

public static MultiValueDictionary<TKey, TElement> ToMultiValueDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, ICollection<TElement>> elementSelector)
{
var dictionary = new MultiValueDictionary<TKey, TElement>();
foreach (var item in source)
Expand All @@ -98,64 +100,6 @@ public static MultiValueDictionary<TKey, TElement> ToMultiValueDictionary<TSourc
}
return dictionary;
}

public static ILookup<TSource, TElement> ToLookup<TSource, TElement>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TElement>> elementsSelector) =>
source.ToLookup(x => x, elementsSelector);

public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, IEnumerable<TElement>> elementsSelector) =>
new Lookup<TKey, TElement>(source.ToDictionary(keySelector, elementsSelector));

public static ILookup<TKey, TElement> ToLookup<TKey, TElement>(this IReadOnlyDictionary<TKey, IEnumerable<TElement>> source) =>
new Lookup<TKey, TElement>(source);

private sealed class Lookup<TKey, TElement> : ILookup<TKey, TElement>
{
public Lookup(IReadOnlyDictionary<TKey, IEnumerable<TElement>> source)
{
Source = source;
}
private IReadOnlyDictionary<TKey, IEnumerable<TElement>> Source { get; }

public IEnumerable<TElement> this[TKey key] => Source[key];

public int Count => Source.Count;

public bool Contains(TKey key) => Source.ContainsKey(key);
public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator() => new Enumerator(this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

private readonly struct Enumerator : IEnumerator<IGrouping<TKey, TElement>>
{
public Enumerator(Lookup<TKey, TElement> lookup)
{
DictEnumerator = lookup.Source.GetEnumerator();
}
private IEnumerator<KeyValuePair<TKey, IEnumerable<TElement>>> DictEnumerator { get; }

public IGrouping<TKey, TElement> Current => new Grouping(DictEnumerator.Current.Key, DictEnumerator.Current.Value);

public void Dispose() => DictEnumerator.Dispose();
public bool MoveNext() => DictEnumerator.MoveNext();
public void Reset() => DictEnumerator.Reset();
object IEnumerator.Current => Current;

private readonly struct Grouping : IGrouping<TKey, TElement>
{
public Grouping(TKey key, IEnumerable<TElement> value)
{
Key = key;
Value = value;
}

public TKey Key { get; }
private IEnumerable<TElement> Value { get; }
public IEnumerator<TElement> GetEnumerator() => Value.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}
}
}

#endregion Extensions
Expand Down

0 comments on commit 7e4c15f

Please sign in to comment.