From beb7a5326bd79cf5da9f43ae6e942ab6be4c51f3 Mon Sep 17 00:00:00 2001 From: Timothy Makkison Date: Fri, 2 Jun 2023 13:37:09 +0100 Subject: [PATCH] feat: cache attribute symbols --- .../Configuration/AttributeDataAccessor.cs | 13 +- .../Descriptors/Configuration.cs | 10 +- .../Descriptors/DescriptorBuilder.cs | 10 +- .../EnsureCapacity/EnsureCapacityBuilder.cs | 15 ++- ...wInstanceObjectMemberMappingBodyBuilder.cs | 6 +- .../DictionaryMappingBuilder.cs | 40 +++--- .../EnumerableMappingBuilder.cs | 77 ++++++----- .../QueryableMappingBuilder.cs | 4 +- .../StringToEnumMappingBuilder.cs | 3 +- .../ObjectFactories/ObjectFactoryBuilder.cs | 3 +- .../Descriptors/UserMethodMappingExtractor.cs | 18 +-- .../Descriptors/WellKnownTypes.cs | 127 +++--------------- src/Riok.Mapperly/MapperGenerator.cs | 3 +- 13 files changed, 132 insertions(+), 197 deletions(-) diff --git a/src/Riok.Mapperly/Configuration/AttributeDataAccessor.cs b/src/Riok.Mapperly/Configuration/AttributeDataAccessor.cs index 256939b8ec..81bcd1ea77 100644 --- a/src/Riok.Mapperly/Configuration/AttributeDataAccessor.cs +++ b/src/Riok.Mapperly/Configuration/AttributeDataAccessor.cs @@ -1,5 +1,6 @@ using System.Reflection; using Microsoft.CodeAnalysis; +using Riok.Mapperly.Descriptors; namespace Riok.Mapperly.Configuration; @@ -8,27 +9,25 @@ namespace Riok.Mapperly.Configuration; /// internal static class AttributeDataAccessor { - public static T? AccessFirstOrDefault(Compilation compilation, ISymbol symbol) - where T : Attribute => Access(compilation, symbol).FirstOrDefault(); + public static T? AccessFirstOrDefault(WellKnownTypes knownTypes, ISymbol symbol) + where T : Attribute => Access(knownTypes, symbol).FirstOrDefault(); /// /// Reads the attribute data and sets it on a newly created instance of . /// If has n type parameters, /// needs to have an accessible ctor with the parameters 0 to n-1 to be of type . /// - /// The compilation. + /// The knownTypes used to get the type symbol. /// The symbol on which the attributes should be read. /// The type of the attribute. /// The type of the data class. If no type parameters are involved, this is usually the same as . /// The attribute data. /// If a property or ctor argument of could not be read on the attribute. - public static IEnumerable Access(Compilation compilation, ISymbol symbol) + public static IEnumerable Access(WellKnownTypes knownTypes, ISymbol symbol) where TAttribute : Attribute { var attrType = typeof(TAttribute); - var attrSymbol = compilation.GetTypeByMetadataName($"{attrType.Namespace}.{attrType.Name}"); - if (attrSymbol == null) - yield break; + var attrSymbol = knownTypes.Get($"{attrType.Namespace}.{attrType.Name}"); var attrDatas = symbol .GetAttributes() diff --git a/src/Riok.Mapperly/Descriptors/Configuration.cs b/src/Riok.Mapperly/Descriptors/Configuration.cs index 5454c7610b..5f7f1d9dd7 100644 --- a/src/Riok.Mapperly/Descriptors/Configuration.cs +++ b/src/Riok.Mapperly/Descriptors/Configuration.cs @@ -14,12 +14,12 @@ public class Configuration /// private readonly Dictionary _defaultConfigurations = new(); - private readonly Compilation _compilation; + private readonly WellKnownTypes _knownTypes; - public Configuration(Compilation compilation, INamedTypeSymbol mapperSymbol) + public Configuration(WellKnownTypes knownTypes, INamedTypeSymbol mapperSymbol) { - _compilation = compilation; - Mapper = AttributeDataAccessor.AccessFirstOrDefault(compilation, mapperSymbol) ?? new(); + _knownTypes = knownTypes; + Mapper = AttributeDataAccessor.AccessFirstOrDefault(knownTypes, mapperSymbol) ?? new(); InitDefaultConfigurations(); } @@ -34,7 +34,7 @@ public T GetOrDefault(IMethodSymbol? userSymbol) public IEnumerable ListConfiguration(IMethodSymbol? userSymbol) where T : Attribute { - return userSymbol == null ? Enumerable.Empty() : AttributeDataAccessor.Access(_compilation, userSymbol); + return userSymbol == null ? Enumerable.Empty() : AttributeDataAccessor.Access(_knownTypes, userSymbol); } private void InitDefaultConfigurations() diff --git a/src/Riok.Mapperly/Descriptors/DescriptorBuilder.cs b/src/Riok.Mapperly/Descriptors/DescriptorBuilder.cs index ee7c3996fa..179027d485 100644 --- a/src/Riok.Mapperly/Descriptors/DescriptorBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/DescriptorBuilder.cs @@ -1,5 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Riok.Mapperly.Abstractions.ReferenceHandling; using Riok.Mapperly.Descriptors.MappingBodyBuilders; using Riok.Mapperly.Descriptors.MappingBuilders; using Riok.Mapperly.Descriptors.ObjectFactories; @@ -22,15 +23,16 @@ public DescriptorBuilder( SourceProductionContext sourceContext, Compilation compilation, ClassDeclarationSyntax mapperSyntax, - INamedTypeSymbol mapperSymbol + INamedTypeSymbol mapperSymbol, + WellKnownTypes wellKnownTypes ) { _mapperDescriptor = new MapperDescriptor(mapperSyntax, mapperSymbol, _methodNameBuilder); _mappingBodyBuilder = new MappingBodyBuilder(_mappings); _builderContext = new SimpleMappingBuilderContext( compilation, - new Configuration(compilation, mapperSymbol), - new WellKnownTypes(compilation), + new Configuration(wellKnownTypes, mapperSymbol), + wellKnownTypes, _mapperDescriptor, sourceContext, new MappingBuilder(_mappings), @@ -95,7 +97,7 @@ private void BuildReferenceHandlingParameters() foreach (var methodMapping in _mappings.MethodMappings) { - methodMapping.EnableReferenceHandling(_builderContext.Types.IReferenceHandler); + methodMapping.EnableReferenceHandling(_builderContext.Types.Get()); } } diff --git a/src/Riok.Mapperly/Descriptors/Enumerables/EnsureCapacity/EnsureCapacityBuilder.cs b/src/Riok.Mapperly/Descriptors/Enumerables/EnsureCapacity/EnsureCapacityBuilder.cs index b4f630868c..19bc4cf4cf 100644 --- a/src/Riok.Mapperly/Descriptors/Enumerables/EnsureCapacity/EnsureCapacityBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/Enumerables/EnsureCapacity/EnsureCapacityBuilder.cs @@ -33,9 +33,10 @@ public static class EnsureCapacityBuilder if (TryGetNonEnumeratedCount(sourceType, types, out var sourceSizeProperty)) return new EnsureCapacityMember(targetSizeProperty, sourceSizeProperty); - sourceType.ImplementsGeneric(types.IEnumerableT, out var iEnumerable); + sourceType.ImplementsGeneric(types.Get(typeof(IEnumerable<>)), out var iEnumerable); - var nonEnumeratedCountMethod = types.Enumerable + var nonEnumeratedCountMethod = types + .Get(typeof(Enumerable)) .GetMembers(TryGetNonEnumeratedCountMethodName) .OfType() .FirstOrDefault( @@ -59,13 +60,19 @@ private static bool TryGetNonEnumeratedCount(ITypeSymbol value, WellKnownTypes t return true; } - if (value.ImplementsGeneric(types.ICollectionT, CountPropertyName, out _, out var hasCollectionCount) && !hasCollectionCount) + if ( + value.ImplementsGeneric(types.Get(typeof(ICollection<>)), CountPropertyName, out _, out var hasCollectionCount) + && !hasCollectionCount + ) { expression = CountPropertyName; return true; } - if (value.ImplementsGeneric(types.IReadOnlyCollectionT, CountPropertyName, out _, out var hasReadOnlyCount) && !hasReadOnlyCount) + if ( + value.ImplementsGeneric(types.Get(typeof(IReadOnlyCollection<>)), CountPropertyName, out _, out var hasReadOnlyCount) + && !hasReadOnlyCount + ) { expression = CountPropertyName; return true; diff --git a/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/NewInstanceObjectMemberMappingBodyBuilder.cs b/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/NewInstanceObjectMemberMappingBodyBuilder.cs index 03dadee5a1..cc3e4d3436 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/NewInstanceObjectMemberMappingBodyBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/NewInstanceObjectMemberMappingBodyBuilder.cs @@ -181,15 +181,15 @@ private static void BuildConstructorMapping(INewInstanceBuilderContext // ctors annotated with [Obsolete] are considered last unless they have a MapperConstructor attribute set var ctorCandidates = namedTargetType.InstanceConstructors .Where(ctor => ctor.IsAccessible()) - .OrderByDescending(x => x.HasAttribute(ctx.BuilderContext.Types.MapperConstructorAttribute)) - .ThenBy(x => x.HasAttribute(ctx.BuilderContext.Types.ObsoleteAttribute)) + .OrderByDescending(x => x.HasAttribute(ctx.BuilderContext.Types.Get())) + .ThenBy(x => x.HasAttribute(ctx.BuilderContext.Types.Get())) .ThenByDescending(x => x.Parameters.Length == 0) .ThenByDescending(x => x.Parameters.Length); foreach (var ctorCandidate in ctorCandidates) { if (!TryBuildConstructorMapping(ctx, ctorCandidate, out var mappedTargetMemberNames, out var constructorParameterMappings)) { - if (ctorCandidate.HasAttribute(ctx.BuilderContext.Types.MapperConstructorAttribute)) + if (ctorCandidate.HasAttribute(ctx.BuilderContext.Types.Get())) { ctx.BuilderContext.ReportDiagnostic( DiagnosticDescriptors.CannotMapToConfiguredConstructor, diff --git a/src/Riok.Mapperly/Descriptors/MappingBuilders/DictionaryMappingBuilder.cs b/src/Riok.Mapperly/Descriptors/MappingBuilders/DictionaryMappingBuilder.cs index c50bcf393a..56e5682cb9 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBuilders/DictionaryMappingBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBuilders/DictionaryMappingBuilder.cs @@ -33,7 +33,7 @@ public static class DictionaryMappingBuilder .GetAllProperties(CountPropertyName) .Any(x => !x.IsStatic && !x.IsIndexer && !x.IsWriteOnly && x.Type.SpecialType == SpecialType.System_Int32); - var targetDictionarySymbol = ctx.Types.DictionaryT.Construct(keyMapping.TargetType, valueMapping.TargetType); + var targetDictionarySymbol = ctx.Types.Get(typeof(Dictionary<,>)).Construct(keyMapping.TargetType, valueMapping.TargetType); ctx.ObjectFactories.TryFindObjectFactory(ctx.Source, ctx.Target, out var dictionaryObjectFactory); return new ForEachSetDictionaryMapping( ctx.Source, @@ -62,7 +62,7 @@ public static class DictionaryMappingBuilder return null; } - if (!ctx.Target.ImplementsGeneric(ctx.Types.IDictionaryT, out _)) + if (!ctx.Target.ImplementsGeneric(ctx.Types.Get(typeof(IDictionary<,>)), out _)) return null; var ensureCapacityStatement = EnsureCapacityBuilder.TryBuildEnsureCapacity(ctx.Source, ctx.Target, ctx.Types); @@ -84,14 +84,14 @@ public static class DictionaryMappingBuilder if (!ctx.IsConversionEnabled(MappingConversionType.Dictionary)) return null; - if (!ctx.Target.ImplementsGeneric(ctx.Types.IDictionaryT, out _)) + if (!ctx.Target.ImplementsGeneric(ctx.Types.Get(typeof(IDictionary<,>)), out _)) return null; if (BuildKeyValueMapping(ctx) is not var (keyMapping, valueMapping)) return null; // if target is an immutable dictionary then don't create a foreach loop - if (ctx.Target.OriginalDefinition.ImplementsGeneric(ctx.Types.IImmutableDictionaryT, out _)) + if (ctx.Target.OriginalDefinition.ImplementsGeneric(ctx.Types.Get(typeof(IImmutableDictionary<,>)), out _)) { ctx.ReportDiagnostic(DiagnosticDescriptors.CannotMapToReadOnlyMember); return null; @@ -134,19 +134,19 @@ private static bool IsDictionaryType(MappingBuilderContext ctx, ITypeSymbol symb if (symbol is not INamedTypeSymbol namedSymbol) return false; - return SymbolEqualityComparer.Default.Equals(namedSymbol.ConstructedFrom, ctx.Types.DictionaryT) - || SymbolEqualityComparer.Default.Equals(namedSymbol.ConstructedFrom, ctx.Types.IDictionaryT) - || SymbolEqualityComparer.Default.Equals(namedSymbol.ConstructedFrom, ctx.Types.IReadOnlyDictionaryT); + return SymbolEqualityComparer.Default.Equals(namedSymbol.ConstructedFrom, ctx.Types.Get(typeof(Dictionary<,>))) + || SymbolEqualityComparer.Default.Equals(namedSymbol.ConstructedFrom, ctx.Types.Get(typeof(IDictionary<,>))) + || SymbolEqualityComparer.Default.Equals(namedSymbol.ConstructedFrom, ctx.Types.Get(typeof(IReadOnlyDictionary<,>))); } private static (ITypeSymbol, ITypeSymbol)? GetDictionaryKeyValueTypes(MappingBuilderContext ctx, ITypeSymbol t) { - if (t.ImplementsGeneric(ctx.Types.IDictionaryT, out var dictionaryImpl)) + if (t.ImplementsGeneric(ctx.Types.Get(typeof(IDictionary<,>)), out var dictionaryImpl)) { return (dictionaryImpl.TypeArguments[0], dictionaryImpl.TypeArguments[1]); } - if (t.ImplementsGeneric(ctx.Types.IReadOnlyDictionaryT, out var readOnlyDictionaryImpl)) + if (t.ImplementsGeneric(ctx.Types.Get(typeof(IReadOnlyDictionary<,>)), out var readOnlyDictionaryImpl)) { return (readOnlyDictionaryImpl.TypeArguments[0], readOnlyDictionaryImpl.TypeArguments[1]); } @@ -156,13 +156,13 @@ private static (ITypeSymbol, ITypeSymbol)? GetDictionaryKeyValueTypes(MappingBui private static (ITypeSymbol, ITypeSymbol)? GetEnumerableKeyValueTypes(MappingBuilderContext ctx, ITypeSymbol t) { - if (!t.ImplementsGeneric(ctx.Types.IEnumerableT, out var enumerableImpl)) + if (!t.ImplementsGeneric(ctx.Types.Get(typeof(IEnumerable<>)), out var enumerableImpl)) return null; if (enumerableImpl.TypeArguments[0] is not INamedTypeSymbol enumeratedType) return null; - if (!SymbolEqualityComparer.Default.Equals(enumeratedType.ConstructedFrom, ctx.Types.KeyValuePairT)) + if (!SymbolEqualityComparer.Default.Equals(enumeratedType.ConstructedFrom, ctx.Types.Get(typeof(KeyValuePair<,>)))) return null; return (enumeratedType.TypeArguments[0], enumeratedType.TypeArguments[1]); @@ -171,8 +171,12 @@ private static (ITypeSymbol, ITypeSymbol)? GetEnumerableKeyValueTypes(MappingBui private static INamedTypeSymbol? GetExplicitIndexer(MappingBuilderContext ctx) { if ( - ctx.Target.ImplementsGeneric(ctx.Types.IDictionaryT, SetterIndexerPropertyName, out var typedInter, out var isExplicit) - && !isExplicit + ctx.Target.ImplementsGeneric( + ctx.Types.Get(typeof(IDictionary<,>)), + SetterIndexerPropertyName, + out var typedInter, + out var isExplicit + ) && !isExplicit ) return null; @@ -185,24 +189,24 @@ private static (ITypeSymbol, ITypeSymbol)? GetEnumerableKeyValueTypes(MappingBui ITypeMapping valueMapping ) { - if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableSortedDictionaryT)) + if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(ImmutableSortedDictionary<,>)))) return new LinqDicitonaryMapping( ctx.Source, ctx.Target, - ctx.Types.ImmutableSortedDictionary.GetStaticGenericMethod(ToImmutableSortedDictionaryMethodName)!, + ctx.Types.Get(typeof(ImmutableSortedDictionary)).GetStaticGenericMethod(ToImmutableSortedDictionaryMethodName)!, keyMapping, valueMapping ); // if target is an ImmutableDictionary or IImmutableDictionary if ( - SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IImmutableDictionaryT) - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableDictionaryT) + SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(IImmutableDictionary<,>))) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(ImmutableDictionary<,>))) ) return new LinqDicitonaryMapping( ctx.Source, ctx.Target, - ctx.Types.ImmutableDictionary.GetStaticGenericMethod(ToImmutableDictionaryMethodName)!, + ctx.Types.Get(typeof(ImmutableDictionary)).GetStaticGenericMethod(ToImmutableDictionaryMethodName)!, keyMapping, valueMapping ); diff --git a/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs b/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs index 72f6125483..a6d3de2254 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs @@ -37,8 +37,8 @@ public static class EnumerableMappingBuilder && ctx.Source.IsArrayType() && ( ctx.Target.IsArrayType() - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IReadOnlyCollectionT) - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IEnumerableT) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(IReadOnlyCollection<>))) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(IEnumerable<>))) ) ) { @@ -80,16 +80,16 @@ public static class EnumerableMappingBuilder if (BuildElementMapping(ctx) is not { } elementMapping) return null; - if (ctx.Target.ImplementsGeneric(ctx.Types.StackT, out _)) + if (ctx.Target.ImplementsGeneric(ctx.Types.Get(typeof(Stack<>)), out _)) return CreateForEach(nameof(Stack.Push)); - if (ctx.Target.ImplementsGeneric(ctx.Types.QueueT, out _)) + if (ctx.Target.ImplementsGeneric(ctx.Types.Get(typeof(Queue<>)), out _)) return CreateForEach(nameof(Queue.Enqueue)); // create a foreach loop with add calls if source is not an array // and ICollection.Add(T): void is implemented and not explicit // ensures add is not called and immutable types - if (!ctx.Target.IsArrayType() && ctx.Target.HasImplicitGenericImplementation(ctx.Types.ICollectionT, AddMethodName)) + if (!ctx.Target.IsArrayType() && ctx.Target.HasImplicitGenericImplementation(ctx.Types.Get(typeof(ICollection<>)), AddMethodName)) return CreateForEach(AddMethodName); // if a mapping could be created for an immutable collection @@ -129,9 +129,9 @@ ForEachAddEnumerableExistingTargetMapping CreateForEach(string methodName) private static LinqEnumerableMapping BuildLinqMapping(MappingBuilderContext ctx, ITypeMapping elementMapping, string? collectMethodName) { - var collectMethod = collectMethodName == null ? null : ctx.Types.Enumerable.GetStaticGenericMethod(collectMethodName); + var collectMethod = collectMethodName == null ? null : ctx.Types.Get(typeof(Enumerable)).GetStaticGenericMethod(collectMethodName); - var selectMethod = elementMapping.IsSynthetic ? null : ctx.Types.Enumerable.GetStaticGenericMethod(SelectMethodName); + var selectMethod = elementMapping.IsSynthetic ? null : ctx.Types.Get(typeof(Enumerable)).GetStaticGenericMethod(SelectMethodName); return new LinqEnumerableMapping(ctx.Source, ctx.Target, elementMapping, selectMethod, collectMethod); } @@ -141,7 +141,7 @@ private static bool HasEnumerableConstructor(MappingBuilderContext ctx, ITypeSym if (ctx.Target is not INamedTypeSymbol namedType) return false; - var typedEnumerable = ctx.Types.IEnumerableT.Construct(typeSymbol); + var typedEnumerable = ctx.Types.Get(typeof(IEnumerable<>)).Construct(typeSymbol); return namedType.Constructors.Any( m => m.Parameters.Length == 1 && SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, typedEnumerable) @@ -150,7 +150,7 @@ private static bool HasEnumerableConstructor(MappingBuilderContext ctx, ITypeSym private static LinqConstructorMapping BuildLinqConstructorMapping(MappingBuilderContext ctx, ITypeMapping elementMapping) { - var selectMethod = elementMapping.IsSynthetic ? null : ctx.Types.Enumerable.GetStaticGenericMethod(SelectMethodName); + var selectMethod = elementMapping.IsSynthetic ? null : ctx.Types.Get(typeof(Enumerable)).GetStaticGenericMethod(SelectMethodName); return new LinqConstructorMapping(ctx.Source, ctx.Target, elementMapping, selectMethod); } @@ -169,7 +169,7 @@ private static LinqConstructorMapping BuildLinqConstructorMapping(MappingBuilder // create a foreach loop with add calls if source is not an array // and ICollection.Add(T): void is implemented and not explicit // ensures add is not called and immutable types - if (!ctx.Target.IsArrayType() && ctx.Target.HasImplicitGenericImplementation(ctx.Types.ICollectionT, AddMethodName)) + if (!ctx.Target.IsArrayType() && ctx.Target.HasImplicitGenericImplementation(ctx.Types.Get(typeof(ICollection<>)), AddMethodName)) { var ensureCapacityStatement = EnsureCapacityBuilder.TryBuildEnsureCapacity(ctx.Source, ctx.Target, ctx.Types); return new ForEachAddEnumerableMapping( @@ -196,7 +196,10 @@ bool elementMappingIsSynthetic // if the target is an IEnumerable don't collect at all // except deep cloning is enabled. - var targetIsIEnumerable = SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IEnumerableT); + var targetIsIEnumerable = SymbolEqualityComparer.Default.Equals( + ctx.Target.OriginalDefinition, + ctx.Types.Get(typeof(IEnumerable<>)) + ); if (targetIsIEnumerable && !ctx.MapperConfiguration.UseDeepCloning) return (true, null); @@ -205,12 +208,12 @@ bool elementMappingIsSynthetic // for performance/space reasons var targetIsReadOnlyCollection = SymbolEqualityComparer.Default.Equals( ctx.Target.OriginalDefinition, - ctx.Types.IReadOnlyCollectionT + ctx.Types.Get(typeof(IReadOnlyCollection<>)) ); var sourceCountIsKnown = ctx.Source.IsArrayType() - || ctx.Source.ImplementsGeneric(ctx.Types.IReadOnlyCollectionT, out _) - || ctx.Source.ImplementsGeneric(ctx.Types.ICollectionT, out _); + || ctx.Source.ImplementsGeneric(ctx.Types.Get(typeof(IReadOnlyCollection<>)), out _) + || ctx.Source.ImplementsGeneric(ctx.Types.Get(typeof(ICollection<>)), out _); if ((targetIsReadOnlyCollection || targetIsIEnumerable) && sourceCountIsKnown) return (true, ToArrayMethodName); @@ -218,10 +221,10 @@ bool elementMappingIsSynthetic return targetIsReadOnlyCollection || targetIsIEnumerable - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IReadOnlyListT) - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IListT) - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ListT) - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ICollectionT) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(IReadOnlyList<>))) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(IList<>))) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(List<>))) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(ICollection<>))) ? (true, ToListMethodName) : (false, null); } @@ -232,48 +235,50 @@ bool elementMappingIsSynthetic if (collectMethod is null) return null; - var selectMethod = elementMapping.IsSynthetic ? null : ctx.Types.Enumerable.GetStaticGenericMethod(SelectMethodName); + var selectMethod = elementMapping.IsSynthetic ? null : ctx.Types.Get(typeof(Enumerable)).GetStaticGenericMethod(SelectMethodName); return new LinqEnumerableMapping(ctx.Source, ctx.Target, elementMapping, selectMethod, collectMethod); } private static IMethodSymbol? ResolveImmutableCollectMethod(MappingBuilderContext ctx) { - if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableArrayT)) - return ctx.Types.ImmutableArray.GetStaticGenericMethod(ToImmutableArrayMethodName); + if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(ImmutableArray<>)))) + return ctx.Types.Get(typeof(ImmutableArray)).GetStaticGenericMethod(ToImmutableArrayMethodName); if ( - SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableListT) - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IImmutableListT) + SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(ImmutableList<>))) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(IImmutableList<>))) ) - return ctx.Types.ImmutableList.GetStaticGenericMethod(ToImmutableListMethodName); + return ctx.Types.Get(typeof(ImmutableList)).GetStaticGenericMethod(ToImmutableListMethodName); if ( - SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableHashSetT) - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IImmutableSetT) + SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(ImmutableHashSet<>))) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(IImmutableSet<>))) ) - return ctx.Types.ImmutableHashSet.GetStaticGenericMethod(ToImmutableHashSetMethodName); + return ctx.Types.Get(typeof(ImmutableHashSet)).GetStaticGenericMethod(ToImmutableHashSetMethodName); if ( - SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableQueueT) - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IImmutableQueueT) + SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(ImmutableQueue<>))) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(IImmutableQueue<>))) ) - return ctx.Types.ImmutableQueue.GetStaticGenericMethod(CreateRangeQueueMethodName); + return ctx.Types.Get(typeof(ImmutableQueue)).GetStaticGenericMethod(CreateRangeQueueMethodName); if ( - SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableStackT) - || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.IImmutableStackT) + SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(ImmutableStack<>))) + || SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(IImmutableStack<>))) ) - return ctx.Types.ImmutableStack.GetStaticGenericMethod(CreateRangeStackMethodName); + return ctx.Types.Get(typeof(ImmutableStack)).GetStaticGenericMethod(CreateRangeStackMethodName); - if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableSortedSetT)) - return ctx.Types.ImmutableSortedSet.GetStaticGenericMethod(ToImmutableSortedSetMethodName); + if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.Get(typeof(ImmutableSortedSet<>)))) + return ctx.Types.Get(typeof(ImmutableSortedSet)).GetStaticGenericMethod(ToImmutableSortedSetMethodName); return null; } private static ITypeSymbol? GetEnumeratedType(MappingBuilderContext ctx, ITypeSymbol type) { - return type.ImplementsGeneric(ctx.Types.IEnumerableT, out var enumerableIntf) ? enumerableIntf.TypeArguments[0] : null; + return type.ImplementsGeneric(ctx.Types.Get(typeof(IEnumerable<>)), out var enumerableIntf) + ? enumerableIntf.TypeArguments[0] + : null; } } diff --git a/src/Riok.Mapperly/Descriptors/MappingBuilders/QueryableMappingBuilder.cs b/src/Riok.Mapperly/Descriptors/MappingBuilders/QueryableMappingBuilder.cs index bdd3c77fba..89539c75d0 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBuilders/QueryableMappingBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBuilders/QueryableMappingBuilder.cs @@ -12,10 +12,10 @@ public static class QueryableMappingBuilder if (!ctx.IsConversionEnabled(MappingConversionType.Queryable)) return null; - if (!ctx.Source.ImplementsGeneric(ctx.Types.IQueryableT, out var sourceQueryable)) + if (!ctx.Source.ImplementsGeneric(ctx.Types.Get(typeof(IQueryable<>)), out var sourceQueryable)) return null; - if (!ctx.Target.ImplementsGeneric(ctx.Types.IQueryableT, out var targetQueryable)) + if (!ctx.Target.ImplementsGeneric(ctx.Types.Get(typeof(IQueryable<>)), out var targetQueryable)) return null; var sourceType = sourceQueryable.TypeArguments[0]; diff --git a/src/Riok.Mapperly/Descriptors/MappingBuilders/StringToEnumMappingBuilder.cs b/src/Riok.Mapperly/Descriptors/MappingBuilders/StringToEnumMappingBuilder.cs index 1c8a33cb39..4b5b1eaba4 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBuilders/StringToEnumMappingBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBuilders/StringToEnumMappingBuilder.cs @@ -15,7 +15,8 @@ public static class StringToEnumMappingBuilder if (ctx.Source.SpecialType != SpecialType.System_String || !ctx.Target.IsEnum()) return null; - var genericEnumParseMethodSupported = ctx.Types.Enum + var genericEnumParseMethodSupported = ctx.Types + .Get() .GetMembers(nameof(Enum.Parse)) .OfType() .Any(x => x.IsGenericMethod); diff --git a/src/Riok.Mapperly/Descriptors/ObjectFactories/ObjectFactoryBuilder.cs b/src/Riok.Mapperly/Descriptors/ObjectFactories/ObjectFactoryBuilder.cs index aeeefab0e7..f4bd7774c9 100644 --- a/src/Riok.Mapperly/Descriptors/ObjectFactories/ObjectFactoryBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/ObjectFactories/ObjectFactoryBuilder.cs @@ -1,4 +1,5 @@ using Microsoft.CodeAnalysis; +using Riok.Mapperly.Abstractions; using Riok.Mapperly.Diagnostics; using Riok.Mapperly.Helpers; @@ -11,7 +12,7 @@ public static ObjectFactoryCollection ExtractObjectFactories(SimpleMappingBuilde var objectFactories = mapperSymbol .GetMembers() .OfType() - .Where(m => m.HasAttribute(ctx.Types.ObjectFactoryAttribute)) + .Where(m => m.HasAttribute(ctx.Types.Get())) .Select(x => BuildObjectFactory(ctx, x)) .WhereNotNull() .ToList(); diff --git a/src/Riok.Mapperly/Descriptors/UserMethodMappingExtractor.cs b/src/Riok.Mapperly/Descriptors/UserMethodMappingExtractor.cs index 8e4cf70232..baf7c6f923 100644 --- a/src/Riok.Mapperly/Descriptors/UserMethodMappingExtractor.cs +++ b/src/Riok.Mapperly/Descriptors/UserMethodMappingExtractor.cs @@ -1,5 +1,7 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis; +using Riok.Mapperly.Abstractions.ReferenceHandling; +using Riok.Mapperly.Abstractions.ReferenceHandling.Internal; using Riok.Mapperly.Descriptors.Mappings; using Riok.Mapperly.Descriptors.Mappings.UserMappings; using Riok.Mapperly.Diagnostics; @@ -97,7 +99,7 @@ bool isStatic methodSymbol, runtimeTargetTypeParams, ctx.MapperConfiguration.UseReferenceHandling, - ctx.Types.PreserveReferenceHandler, + ctx.Types.Get(), GetTypeSwitchNullArm(methodSymbol, runtimeTargetTypeParams, null), ctx.Compilation.ObjectType ); @@ -116,7 +118,7 @@ bool isStatic typeParameters.Value, parameters, ctx.MapperConfiguration.UseReferenceHandling, - ctx.Types.PreserveReferenceHandler, + ctx.Types.Get(), GetTypeSwitchNullArm(methodSymbol, parameters, typeParameters), ctx.Compilation.ObjectType ); @@ -136,7 +138,7 @@ bool isStatic parameters.Target.Value, parameters.ReferenceHandler, ctx.MapperConfiguration.UseReferenceHandling, - ctx.Types.PreserveReferenceHandler + ctx.Types.Get() ); } @@ -145,7 +147,7 @@ bool isStatic parameters.Source, parameters.ReferenceHandler, ctx.MapperConfiguration.UseReferenceHandling, - ctx.Types.PreserveReferenceHandler + ctx.Types.Get() ); } @@ -223,7 +225,7 @@ private static bool BuildRuntimeTargetTypeMappingParameters( method.Parameters.FirstOrDefault(p => p.Ordinal != sourceParameter.Value.Ordinal && p.Ordinal != refHandlerParameterOrdinal) ); expectedParametersCount++; - if (targetTypeParameter == null || !SymbolEqualityComparer.Default.Equals(targetTypeParameter.Value.Type, ctx.Types.Type)) + if (targetTypeParameter == null || !SymbolEqualityComparer.Default.Equals(targetTypeParameter.Value.Type, ctx.Types.Get())) { parameters = null; return false; @@ -292,19 +294,19 @@ private static bool BuildParameters( private static MethodParameter? BuildReferenceHandlerParameter(SimpleMappingBuilderContext ctx, IMethodSymbol method) { - var refHandlerParameterSymbol = method.Parameters.FirstOrDefault(p => p.HasAttribute(ctx.Types.ReferenceHandlerAttribute)); + var refHandlerParameterSymbol = method.Parameters.FirstOrDefault(p => p.HasAttribute(ctx.Types.Get())); if (refHandlerParameterSymbol == null) return null; var refHandlerParameter = new MethodParameter(refHandlerParameterSymbol); - if (!SymbolEqualityComparer.Default.Equals(ctx.Types.IReferenceHandler, refHandlerParameter.Type)) + if (!SymbolEqualityComparer.Default.Equals(ctx.Types.Get(), refHandlerParameter.Type)) { ctx.ReportDiagnostic( DiagnosticDescriptors.ReferenceHandlerParameterWrongType, refHandlerParameterSymbol, method.ContainingType.ToDisplayString(), method.Name, - ctx.Types.IReferenceHandler.ToDisplayString(), + ctx.Types.Get().ToDisplayString(), refHandlerParameterSymbol.Type.ToDisplayString() ); } diff --git a/src/Riok.Mapperly/Descriptors/WellKnownTypes.cs b/src/Riok.Mapperly/Descriptors/WellKnownTypes.cs index e992d36771..28e8285e3c 100644 --- a/src/Riok.Mapperly/Descriptors/WellKnownTypes.cs +++ b/src/Riok.Mapperly/Descriptors/WellKnownTypes.cs @@ -1,127 +1,40 @@ -using System.Collections.Immutable; using Microsoft.CodeAnalysis; -using Riok.Mapperly.Abstractions; -using Riok.Mapperly.Abstractions.ReferenceHandling; -using Riok.Mapperly.Abstractions.ReferenceHandling.Internal; namespace Riok.Mapperly.Descriptors; public class WellKnownTypes { private readonly Compilation _compilation; - - private INamedTypeSymbol? _referenceHandlerAttribute; - private INamedTypeSymbol? _objectFactoryAttribute; - private INamedTypeSymbol? _mapperConstructorAttribute; - - private INamedTypeSymbol? _obsoleteAttribute; - - private INamedTypeSymbol? _iReferenceHandler; - private INamedTypeSymbol? _preserveReferenceHandler; - - private INamedTypeSymbol? _iDictionaryT; - private INamedTypeSymbol? _iReadOnlyDictionaryT; - private INamedTypeSymbol? _iEnumerableT; - private INamedTypeSymbol? _enumerable; - private INamedTypeSymbol? _iCollectionT; - private INamedTypeSymbol? _iReadOnlyCollectionT; - private INamedTypeSymbol? _iListT; - private INamedTypeSymbol? _listT; - private INamedTypeSymbol? _stackT; - private INamedTypeSymbol? _queueT; - private INamedTypeSymbol? _iReadOnlyListT; - private INamedTypeSymbol? _keyValuePairT; - private INamedTypeSymbol? _dictionaryT; - private INamedTypeSymbol? _enum; - private INamedTypeSymbol? _type; - - private INamedTypeSymbol? _immutableArray; - private INamedTypeSymbol? _immutableArrayT; - private INamedTypeSymbol? _immutableList; - private INamedTypeSymbol? _immutableListT; - private INamedTypeSymbol? _iImmutableListT; - private INamedTypeSymbol? _immutableHashSet; - private INamedTypeSymbol? _immutableHashSetT; - private INamedTypeSymbol? _iImmutableSetT; - private INamedTypeSymbol? _immutableQueue; - private INamedTypeSymbol? _immutableQueueT; - private INamedTypeSymbol? _iImmutableQueueT; - private INamedTypeSymbol? _immutableStack; - private INamedTypeSymbol? _immutableStackT; - private INamedTypeSymbol? _iImmutableStackT; - private INamedTypeSymbol? _immutableSortedSet; - private INamedTypeSymbol? _immutableSortedSetT; - private INamedTypeSymbol? _immutableDictionary; - private INamedTypeSymbol? _immutableDictionaryT; - private INamedTypeSymbol? _iImmutableDictionaryT; - private INamedTypeSymbol? _immutableSortedDictionary; - private INamedTypeSymbol? _immutableSortedDictionaryT; - - private INamedTypeSymbol? _iQueryableT; - - private INamedTypeSymbol? _dateOnly; - private INamedTypeSymbol? _timeOnly; + private readonly Dictionary _cachedTypes = new(); internal WellKnownTypes(Compilation compilation) { _compilation = compilation; } - public INamedTypeSymbol ReferenceHandlerAttribute => _referenceHandlerAttribute ??= GetTypeSymbol(typeof(ReferenceHandlerAttribute)); - public INamedTypeSymbol ObjectFactoryAttribute => _objectFactoryAttribute ??= GetTypeSymbol(typeof(ObjectFactoryAttribute)); - public INamedTypeSymbol MapperConstructorAttribute => _mapperConstructorAttribute ??= GetTypeSymbol(typeof(MapperConstructorAttribute)); - public INamedTypeSymbol ObsoleteAttribute => _obsoleteAttribute ??= GetTypeSymbol(typeof(ObsoleteAttribute)); - public INamedTypeSymbol IReferenceHandler => _iReferenceHandler ??= GetTypeSymbol(typeof(IReferenceHandler)); - public INamedTypeSymbol PreserveReferenceHandler => _preserveReferenceHandler ??= GetTypeSymbol(typeof(PreserveReferenceHandler)); - public INamedTypeSymbol IDictionaryT => _iDictionaryT ??= GetTypeSymbol(typeof(IDictionary<,>)); - public INamedTypeSymbol IReadOnlyDictionaryT => _iReadOnlyDictionaryT ??= GetTypeSymbol(typeof(IReadOnlyDictionary<,>)); - public INamedTypeSymbol IEnumerableT => _iEnumerableT ??= GetTypeSymbol(typeof(IEnumerable<>)); - public INamedTypeSymbol Enumerable => _enumerable ??= GetTypeSymbol(typeof(Enumerable)); - public INamedTypeSymbol ICollectionT => _iCollectionT ??= GetTypeSymbol(typeof(ICollection<>)); - public INamedTypeSymbol IReadOnlyCollectionT => _iReadOnlyCollectionT ??= GetTypeSymbol(typeof(IReadOnlyCollection<>)); - public INamedTypeSymbol IListT => _iListT ??= GetTypeSymbol(typeof(IList<>)); - public INamedTypeSymbol ListT => _listT ??= GetTypeSymbol(typeof(List<>)); - public INamedTypeSymbol StackT => _stackT ??= GetTypeSymbol(typeof(Stack<>)); - public INamedTypeSymbol QueueT => _queueT ??= GetTypeSymbol(typeof(Queue<>)); - public INamedTypeSymbol IReadOnlyListT => _iReadOnlyListT ??= GetTypeSymbol(typeof(IReadOnlyList<>)); - public INamedTypeSymbol KeyValuePairT => _keyValuePairT ??= GetTypeSymbol(typeof(KeyValuePair<,>)); - public INamedTypeSymbol DictionaryT => _dictionaryT ??= GetTypeSymbol(typeof(Dictionary<,>)); - public INamedTypeSymbol Enum => _enum ??= GetTypeSymbol(typeof(Enum)); - public INamedTypeSymbol Type => _type ??= GetTypeSymbol(typeof(Type)); - public INamedTypeSymbol IQueryableT => _iQueryableT ??= GetTypeSymbol(typeof(IQueryable<>)); + // use string type name as they are not available in netstandard2.0 + public INamedTypeSymbol? DateOnly => TryGet("System.DateOnly"); - public INamedTypeSymbol ImmutableArray => _immutableArray ??= GetTypeSymbol(typeof(ImmutableArray)); - public INamedTypeSymbol ImmutableArrayT => _immutableArrayT ??= GetTypeSymbol(typeof(ImmutableArray<>)); - public INamedTypeSymbol ImmutableList => _immutableList ??= GetTypeSymbol(typeof(ImmutableList)); - public INamedTypeSymbol ImmutableListT => _immutableListT ??= GetTypeSymbol(typeof(ImmutableList<>)); - public INamedTypeSymbol IImmutableListT => _iImmutableListT ??= GetTypeSymbol(typeof(IImmutableList<>)); - public INamedTypeSymbol ImmutableHashSet => _immutableHashSet ??= GetTypeSymbol(typeof(ImmutableHashSet)); - public INamedTypeSymbol ImmutableHashSetT => _immutableHashSetT ??= GetTypeSymbol(typeof(ImmutableHashSet<>)); - public INamedTypeSymbol IImmutableSetT => _iImmutableSetT ??= GetTypeSymbol(typeof(IImmutableSet<>)); - public INamedTypeSymbol ImmutableQueue => _immutableQueue ??= GetTypeSymbol(typeof(ImmutableQueue)); - public INamedTypeSymbol ImmutableQueueT => _immutableQueueT ??= GetTypeSymbol(typeof(ImmutableQueue<>)); - public INamedTypeSymbol IImmutableQueueT => _iImmutableQueueT ??= GetTypeSymbol(typeof(IImmutableQueue<>)); - public INamedTypeSymbol ImmutableStack => _immutableStack ??= GetTypeSymbol(typeof(ImmutableStack)); - public INamedTypeSymbol ImmutableStackT => _immutableStackT ??= GetTypeSymbol(typeof(ImmutableStack<>)); - public INamedTypeSymbol IImmutableStackT => _iImmutableStackT ??= GetTypeSymbol(typeof(IImmutableStack<>)); - public INamedTypeSymbol ImmutableSortedSet => _immutableSortedSet ??= GetTypeSymbol(typeof(ImmutableSortedSet)); - public INamedTypeSymbol ImmutableSortedSetT => _immutableSortedSetT ??= GetTypeSymbol(typeof(ImmutableSortedSet<>)); - public INamedTypeSymbol ImmutableDictionary => _immutableDictionary ??= GetTypeSymbol(typeof(ImmutableDictionary)); - public INamedTypeSymbol IImmutableDictionaryT => _iImmutableDictionaryT ??= GetTypeSymbol(typeof(IImmutableDictionary<,>)); - public INamedTypeSymbol ImmutableDictionaryT => _immutableDictionaryT ??= GetTypeSymbol(typeof(ImmutableDictionary<,>)); + public INamedTypeSymbol? TimeOnly => TryGet("System.TimeOnly"); - public INamedTypeSymbol ImmutableSortedDictionary => _immutableSortedDictionary ??= GetTypeSymbol(typeof(ImmutableSortedDictionary)); - public INamedTypeSymbol ImmutableSortedDictionaryT => - _immutableSortedDictionaryT ??= GetTypeSymbol(typeof(ImmutableSortedDictionary<,>)); + public INamedTypeSymbol Get() => Get(typeof(T).FullName); - // use string type name as they are not available in netstandard2.0 - public INamedTypeSymbol? DateOnly => _dateOnly ??= GetTypeSymbol("System.DateOnly"); + public INamedTypeSymbol Get(Type type) => + Get(type.FullName ?? throw new InvalidOperationException("Could not get name of type " + type)); - public INamedTypeSymbol? TimeOnly => _timeOnly ??= GetTypeSymbol("System.TimeOnly"); + public INamedTypeSymbol Get(string typeFullName) => + TryGet(typeFullName) ?? throw new InvalidOperationException("Could not get type " + typeFullName); - private INamedTypeSymbol GetTypeSymbol(Type type) => - _compilation.GetTypeByMetadataName(type.FullName ?? throw new InvalidOperationException("Could not get name of type " + type)) - ?? throw new InvalidOperationException("Could not get type " + type.FullName); + private INamedTypeSymbol? TryGet(string typeFullName) + { + if (_cachedTypes.TryGetValue(typeFullName, out var typeSymbol)) + { + return typeSymbol; + } + + typeSymbol = _compilation.GetTypeByMetadataName(typeFullName); + _cachedTypes.Add(typeFullName, typeSymbol); - private INamedTypeSymbol? GetTypeSymbol(string typeFullName) => _compilation.GetTypeByMetadataName(typeFullName); + return typeSymbol; + } } diff --git a/src/Riok.Mapperly/MapperGenerator.cs b/src/Riok.Mapperly/MapperGenerator.cs index 47cc8e087b..b848ad3738 100644 --- a/src/Riok.Mapperly/MapperGenerator.cs +++ b/src/Riok.Mapperly/MapperGenerator.cs @@ -37,6 +37,7 @@ private static void Execute(Compilation compilation, ImmutableArray