@@ -86,8 +86,7 @@ internal abstract class CheckTypeProperties : ICheckTypeProperties
8686 private readonly ITypeParameterUtility _typeParameterUtility ;
8787 private readonly WellKnownTypes _wellKnownTypes ;
8888
89- private readonly Dictionary < INamedTypeSymbol , IDictionary < ITypeSymbol , ISet < object > > > _typeToKeyToValue = new ( ) ;
90- private readonly Dictionary < INamedTypeSymbol , int > _decorationToOrdinal ;
89+ private readonly Dictionary < INamedTypeSymbol , IDictionary < ITypeSymbol , ISet < object > > > _typeToKeyToValue = new ( CustomSymbolEqualityComparer . Default ) ;
9190
9291 internal CheckTypeProperties (
9392 ICurrentlyConsideredTypes currentlyConsideredTypes ,
@@ -139,23 +138,6 @@ internal CheckTypeProperties(
139138 implementationType . OriginalDefinition ,
140139 new Dictionary < ITypeSymbol , ISet < object > > { { keyType , new HashSet < object > { keyValue } } } ) ;
141140 }
142-
143- _decorationToOrdinal = currentlyConsideredTypes . DecoratorTypes
144- . SelectMany ( d => d . GetAttributes ( ) . Select ( a => ( d , a ) ) )
145- . Select ( t =>
146- {
147- var ( decorator , attribute ) = t ;
148- if ( ! currentlyConsideredTypes . DecorationOrdinalAttributeTypes . Any ( a =>
149- CustomSymbolEqualityComparer . Default . Equals ( a , attribute . AttributeClass ) ) )
150- return ( ( INamedTypeSymbol DecorationImplementationType , int Ordinal ) ? ) null ;
151- return (
152- DecorationImplementationType : decorator ,
153- Ordinal : attribute . ConstructorArguments [ 0 ] . Value is int ordinal ? ordinal : 0 ) ;
154- } )
155- . Where ( t => t is not null )
156- . Select ( t => t ?? throw new ImpossibleDieException ( ) )
157- . Concat ( currentlyConsideredTypes . DecorationOrdinalChoices )
158- . ToDictionary ( t => t . DecorationImplementationType , t => t . Ordinal ) ;
159141 }
160142
161143 public DisposalType ShouldDisposalBeManaged ( INamedTypeSymbol implementationType )
@@ -167,41 +149,43 @@ public DisposalType ShouldDisposalBeManaged(INamedTypeSymbol implementationType)
167149
168150 if ( _wellKnownTypes . IAsyncDisposable is not null
169151 && implementationType . OriginalDefinitionIfUnbound ( ) . AllInterfaces . Contains ( _wellKnownTypes . IAsyncDisposable )
170- && ! _currentlyConsideredTypes . AsyncTransientTypes . Contains ( implementationType . UnboundIfGeneric ( ) ) )
152+ && ! _currentlyConsideredTypes . IsAsyncTransient ( implementationType . UnboundIfGeneric ( ) ) )
171153 ret |= DisposalType . Async ;
172154
173155 if ( implementationType . OriginalDefinitionIfUnbound ( ) . AllInterfaces . Contains ( _wellKnownTypes . IDisposable )
174- && ! _currentlyConsideredTypes . SyncTransientTypes . Contains ( implementationType . UnboundIfGeneric ( ) ) )
156+ && ! _currentlyConsideredTypes . IsSyncTransient ( implementationType . UnboundIfGeneric ( ) ) )
175157 ret |= DisposalType . Sync ;
176158
177159 return ret ;
178160 }
179161
180162 public ScopeLevel ShouldBeScopeRoot ( INamedTypeSymbol implementationType )
181163 {
182- if ( _currentlyConsideredTypes . TransientScopeRootTypes . Contains ( implementationType . UnboundIfGeneric ( ) ) )
164+ if ( _currentlyConsideredTypes . IsTransientScopeRoot ( implementationType . UnboundIfGeneric ( ) ) )
183165 return ScopeLevel . TransientScope ;
184- if ( _currentlyConsideredTypes . ScopeRootTypes . Contains ( implementationType . UnboundIfGeneric ( ) ) )
166+ if ( _currentlyConsideredTypes . IsScopeRoot ( implementationType . UnboundIfGeneric ( ) ) )
185167 return ScopeLevel . Scope ;
186168 return ScopeLevel . None ;
187169 }
188170
189- public bool ShouldBeComposite ( INamedTypeSymbol interfaceType ) => _currentlyConsideredTypes . InterfaceToComposite . ContainsKey ( interfaceType . UnboundIfGeneric ( ) ) ;
171+ public bool ShouldBeComposite ( INamedTypeSymbol interfaceType ) => _currentlyConsideredTypes . HasComposite ( interfaceType ) ;
190172 public ScopeLevel GetScopeLevelFor ( INamedTypeSymbol implementationType )
191173 {
192174 var unbound = implementationType . UnboundIfGeneric ( ) ;
193- if ( _currentlyConsideredTypes . ContainerInstanceTypes . Contains ( unbound ) )
175+ if ( _currentlyConsideredTypes . IsContainerInstance ( unbound ) )
194176 return ScopeLevel . Container ;
195- if ( _currentlyConsideredTypes . TransientScopeInstanceTypes . Contains ( unbound ) )
177+ if ( _currentlyConsideredTypes . IsTransientScopeInstance ( unbound ) )
196178 return ScopeLevel . TransientScope ;
197- if ( _currentlyConsideredTypes . ScopeInstanceTypes . Contains ( unbound ) )
179+ if ( _currentlyConsideredTypes . IsScopeInstance ( unbound ) )
198180 return ScopeLevel . Scope ;
199181 return ScopeLevel . None ;
200182 }
201183
202184 public INamedTypeSymbol ? GetCompositeFor ( INamedTypeSymbol interfaceType )
203185 {
204- var compositeImplementation = _currentlyConsideredTypes . InterfaceToComposite [ interfaceType . UnboundIfGeneric ( ) ] ;
186+ var compositeImplementation = _currentlyConsideredTypes . GetCompositeFor ( interfaceType ) ;
187+ if ( compositeImplementation is null )
188+ return null ;
205189 var implementations = GetClosedImplementations (
206190 interfaceType ,
207191 [ compositeImplementation ] ,
@@ -243,7 +227,7 @@ when implementationType.InstanceConstructors.SingleOrDefault(c => c.Parameters.L
243227 } ;
244228 }
245229
246- public bool ShouldBeDecorated ( INamedTypeSymbol interfaceType ) => _currentlyConsideredTypes . InterfaceToDecorators . ContainsKey ( interfaceType . UnboundIfGeneric ( ) ) ;
230+ public bool ShouldBeDecorated ( INamedTypeSymbol interfaceType ) => _currentlyConsideredTypes . HasDecorators ( interfaceType ) ;
247231
248232 public IReadOnlyList < INamedTypeSymbol > GetDecorationSequenceFor ( INamedTypeSymbol interfaceType ,
249233 INamedTypeSymbol implementationType )
@@ -264,10 +248,10 @@ public IReadOnlyList<INamedTypeSymbol> GetDecorationSequenceFor(INamedTypeSymbol
264248 found = true ;
265249 }
266250 }
267-
268- if ( ! found && _currentlyConsideredTypes . InterfaceToDecorators . TryGetValue ( interfaceType . UnboundIfGeneric ( ) , out var allDecorators ) )
251+ var allDecorators = _currentlyConsideredTypes . GetDecoratorsFor ( interfaceType ) ;
252+ if ( ! found && allDecorators . Length > 0 )
269253 sequence = allDecorators
270- . OrderBy ( d => _decorationToOrdinal . TryGetValue ( d , out var ordinal ) ? ordinal : 0 ) ;
254+ . OrderBy ( d => _currentlyConsideredTypes . GetDecorationOrdinal ( d ) ) ;
271255
272256 return sequence
273257 . Select ( imp =>
@@ -287,8 +271,7 @@ public IReadOnlyList<INamedTypeSymbol> GetDecorationSequenceFor(INamedTypeSymbol
287271 . ToList ( ) ;
288272 }
289273
290- public INamedTypeSymbol ? MapToSingleFittingImplementation ( INamedTypeSymbol type ,
291- InjectionKey ? injectionKey )
274+ public INamedTypeSymbol ? MapToSingleFittingImplementation ( INamedTypeSymbol type , InjectionKey ? injectionKey )
292275 {
293276 var choice =
294277 _currentlyConsideredTypes . ImplementationChoices . TryGetValue ( type . UnboundIfGeneric ( ) , out var choice0 )
@@ -317,8 +300,8 @@ public IReadOnlyList<INamedTypeSymbol> GetDecorationSequenceFor(INamedTypeSymbol
317300
318301 if ( type is { TypeKind : not TypeKind . Interface , IsAbstract : false , IsStatic : false } )
319302 {
320- if ( _currentlyConsideredTypes . DecoratorTypes . Contains ( type ) ||
321- _currentlyConsideredTypes . CompositeTypes . Contains ( type ) )
303+ if ( _currentlyConsideredTypes . IsDecorator ( type ) ||
304+ _currentlyConsideredTypes . IsComposite ( type ) )
322305 // if concrete type is decorator or composite then just shortcut
323306 return type ;
324307 var possibleConcreteTypeImplementations = FilterByInjectionKey (
@@ -335,24 +318,22 @@ public IReadOnlyList<INamedTypeSymbol> GetDecorationSequenceFor(INamedTypeSymbol
335318 return list . Count == 1 ? list [ 0 ] : null ;
336319 }
337320
338- var possibleImplementations = _currentlyConsideredTypes . ImplementationMap . TryGetValue ( type . UnboundIfGeneric ( ) , out var implementations )
339- ? FilterByInjectionKey (
321+ var implementations = _currentlyConsideredTypes . GetAllImplementingTypes ( type ) ;
322+ var possibleImplementations = FilterByInjectionKey (
340323 GetClosedImplementations (
341324 type ,
342325 [ ..implementations ] ,
343326 true ,
344327 false ,
345328 false ) ,
346- injectionKey )
347- : [ ] ;
329+ injectionKey ) ;
348330
349331 var list2 = possibleImplementations . Take ( 2 ) . ToList ( ) ;
350332
351333 return list2 . Count == 1 ? list2 [ 0 ] : null ;
352334 }
353335
354- public IReadOnlyList < INamedTypeSymbol > MapToImplementations ( INamedTypeSymbol typeSymbol ,
355- InjectionKey ? injectionKey )
336+ public IReadOnlyList < INamedTypeSymbol > MapToImplementations ( INamedTypeSymbol typeSymbol , InjectionKey ? injectionKey )
356337 {
357338 if ( _currentlyConsideredTypes
358339 . ImplementationCollectionChoices
@@ -368,17 +349,15 @@ public IReadOnlyList<INamedTypeSymbol> MapToImplementations(INamedTypeSymbol typ
368349 injectionKey ) . ToList ( ) ;
369350 }
370351
371- return _currentlyConsideredTypes . ImplementationMap . TryGetValue ( typeSymbol . UnboundIfGeneric ( ) ,
372- out var implementations )
373- ? FilterByInjectionKey (
352+ return FilterByInjectionKey (
374353 GetClosedImplementations (
375354 typeSymbol ,
376- [ ..implementations ] ,
355+ [ .._currentlyConsideredTypes . GetAllImplementingTypes ( typeSymbol . UnboundIfGeneric ( ) ) ] ,
377356 false ,
378357 false ,
379358 false ) ,
380- injectionKey ) . ToList ( )
381- : Array . Empty < INamedTypeSymbol > ( ) ;
359+ injectionKey )
360+ . ToList ( ) ;
382361 }
383362
384363 private IEnumerable < INamedTypeSymbol > FilterByInjectionKey (
@@ -424,15 +403,15 @@ private IEnumerable<INamedTypeSymbol> GetClosedImplementations(
424403 var unboundImplementation = implementation . UnboundIfGeneric ( ) ;
425404 var originalImplementation = implementation . OriginalDefinitionIfUnbound ( ) ;
426405
427- var isCompositeImplementation = _currentlyConsideredTypes . CompositeTypes . Contains ( unboundImplementation ) ;
406+ var isCompositeImplementation = _currentlyConsideredTypes . IsComposite ( unboundImplementation ) ;
428407 if ( chooseComposite && ! isCompositeImplementation || ! chooseComposite && isCompositeImplementation )
429408 continue ;
430- var isDecoratorImplementation = _currentlyConsideredTypes . DecoratorTypes . Contains ( unboundImplementation ) ;
409+ var isDecoratorImplementation = _currentlyConsideredTypes . IsDecorator ( unboundImplementation ) ;
431410 if ( chooseDecorator && ! isDecoratorImplementation || ! chooseDecorator && isDecoratorImplementation )
432411 continue ;
433412 if ( ! chooseComposite
434413 && ! chooseDecorator
435- && ! _currentlyConsideredTypes . AllConsideredImplementations . Contains ( unboundImplementation ) )
414+ && ! _currentlyConsideredTypes . ImplementationConsidered ( unboundImplementation ) )
436415 continue ;
437416 if ( ! implementation . IsGenericType )
438417 {
@@ -559,21 +538,27 @@ IImmutableSet<INamedTypeSymbol> GetSubstitutes(
559538
560539 public ( INamedTypeSymbol Type , IMethodSymbol Initializer ) ? GetInitializerFor ( INamedTypeSymbol implementationType )
561540 {
562- if ( _currentlyConsideredTypes . ImplementationToInitializer . TryGetValue ( implementationType . UnboundIfGeneric ( ) , out var tuple ) )
563- {
564- var abstractionType = implementationType
565- . AllDerivedTypesAndSelf ( )
566- . FirstOrDefault ( t => CustomSymbolEqualityComparer . Default . Equals ( t . UnboundIfGeneric ( ) , tuple . Item1 . UnboundIfGeneric ( ) ) ) ;
567-
568- var initializerMethod = implementationType
569- . AllDerivedTypesAndSelf ( )
570- . SelectMany ( t => t . GetMembers ( tuple . Item2 . Name ) )
571- . OfType < IMethodSymbol > ( )
572- . FirstOrDefault ( m => CustomSymbolEqualityComparer . Default . Equals ( m . OriginalDefinition , tuple . Item2 . OriginalDefinition ) ) ;
573-
574- return abstractionType is not null && initializerMethod is not null ? ( abstractionType , initializerMethod ) : null ;
575- }
576- return null ;
541+ var initializerInfo = _currentlyConsideredTypes . GetInitializerFor ( implementationType ) ;
542+ if ( initializerInfo is null )
543+ return null ;
544+
545+ var ( abstractionType , initializerMethodDef ) = initializerInfo . Value ;
546+
547+ var concreteAbstractionType = implementationType
548+ . AllDerivedTypesAndSelf ( )
549+ . FirstOrDefault ( t => CustomSymbolEqualityComparer . Default . Equals (
550+ t . UnboundIfGeneric ( ) , abstractionType . UnboundIfGeneric ( ) ) ) ;
551+
552+ var initializerMethod = implementationType
553+ . AllDerivedTypesAndSelf ( )
554+ . SelectMany ( t => t . GetMembers ( initializerMethodDef . Name ) )
555+ . OfType < IMethodSymbol > ( )
556+ . FirstOrDefault ( m => CustomSymbolEqualityComparer . Default . Equals (
557+ m . OriginalDefinition , initializerMethodDef . OriginalDefinition ) ) ;
558+
559+ return concreteAbstractionType is not null && initializerMethod is not null
560+ ? ( concreteAbstractionType , initializerMethod )
561+ : null ;
577562 }
578563
579564 public IReadOnlyList < IPropertySymbol > ? GetPropertyChoicesFor ( INamedTypeSymbol implementationType )
0 commit comments