Compiling state (replace SingleOrDefault by firstOrDefault)

This commit is contained in:
CodeLiturgy 2022-08-18 15:13:17 +01:00
parent 7ba619240c
commit 6768e12bb1
8 changed files with 52 additions and 26 deletions

View File

@ -0,0 +1,6 @@
namespace BlueWest.Data;
public class TestData
{
}

View File

@ -18,6 +18,7 @@
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DocumentationFile>bin\Release\MapTo.xml</DocumentationFile> <DocumentationFile>bin\Release\MapTo.xml</DocumentationFile>
<Optimize>false</Optimize>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -33,11 +33,13 @@ namespace MapTo.Extensions
public static AttributeSyntax? GetAttribute(this TypeDeclarationSyntax typeDeclarationSyntax, string attributeName) public static AttributeSyntax? GetAttribute(this TypeDeclarationSyntax typeDeclarationSyntax, string attributeName)
{ {
return typeDeclarationSyntax.AttributeLists var attributeLists = typeDeclarationSyntax.AttributeLists;
.SelectMany(al => al.Attributes) var selection = attributeLists
.SingleOrDefault(a => .SelectMany(al => al.Attributes);
(a.Name as IdentifierNameSyntax)?.Identifier.ValueText == attributeName || var result = selection
((a.Name as QualifiedNameSyntax)?.Right as IdentifierNameSyntax)?.Identifier.ValueText == attributeName); .FirstOrDefault();
return result;
} }
public static bool HasAttribute(this ISymbol symbol, ITypeSymbol attributeSymbol) => public static bool HasAttribute(this ISymbol symbol, ITypeSymbol attributeSymbol) =>
@ -86,7 +88,7 @@ namespace MapTo.Extensions
public static IPropertySymbol? FindProperty(this IEnumerable<IPropertySymbol> properties, IPropertySymbol targetProperty) public static IPropertySymbol? FindProperty(this IEnumerable<IPropertySymbol> properties, IPropertySymbol targetProperty)
{ {
return properties.SingleOrDefault(p => return properties.FirstOrDefault(p =>
p.Name == targetProperty.Name && p.Name == targetProperty.Name &&
(p.NullableAnnotation != NullableAnnotation.Annotated || (p.NullableAnnotation != NullableAnnotation.Annotated ||
p.NullableAnnotation == NullableAnnotation.Annotated && p.NullableAnnotation == NullableAnnotation.Annotated &&

View File

@ -20,7 +20,7 @@ namespace MapTo
var attributeSyntax = attributes var attributeSyntax = attributes
.SelectMany(a => a.Attributes) .SelectMany(a => a.Attributes)
.SingleOrDefault(a => a.Name is .FirstOrDefault(a => a.Name is
IdentifierNameSyntax { Identifier: { ValueText: MapFromAttributeSource.AttributeName } } // For: [MapFrom] IdentifierNameSyntax { Identifier: { ValueText: MapFromAttributeSource.AttributeName } } // For: [MapFrom]
or or
QualifiedNameSyntax // For: [MapTo.MapFrom] QualifiedNameSyntax // For: [MapTo.MapFrom]

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading;
using MapTo.Extensions; using MapTo.Extensions;
using MapTo.Sources; using MapTo.Sources;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
@ -70,6 +72,8 @@ namespace MapTo
public static MappingContext Create(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax) public static MappingContext Create(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
{ {
//SpinWait.SpinUntil(() => Debugger.IsAttached);
MappingContext context = typeSyntax switch MappingContext context = typeSyntax switch
{ {
StructDeclarationSyntax => new StructMappingContext(compilation, sourceGenerationOptions, typeSyntax), StructDeclarationSyntax => new StructMappingContext(compilation, sourceGenerationOptions, typeSyntax),
@ -107,20 +111,20 @@ namespace MapTo
var propertyName = property var propertyName = property
.GetAttribute(MapPropertyAttributeTypeSymbol) .GetAttribute(MapPropertyAttributeTypeSymbol)
?.NamedArguments ?.NamedArguments
.SingleOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName) .FirstOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName)
.Value.Value as string ?? property.Name; .Value.Value as string ?? property.Name;
return sourceProperties.SingleOrDefault(p => p.Name == propertyName); return sourceProperties.FirstOrDefault(p => p.Name == propertyName);
} }
protected IFieldSymbol? FindSourceField(IEnumerable<IFieldSymbol> sourceProperties, ISymbol property) protected IFieldSymbol? FindSourceField(IEnumerable<IFieldSymbol> sourceProperties, ISymbol property)
{ {
var propertyName = property var propertyName = property
.GetAttribute(MapPropertyAttributeTypeSymbol) .GetAttribute(MapPropertyAttributeTypeSymbol)
?.NamedArguments ?.NamedArguments
.SingleOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName) .FirstOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName)
.Value.Value as string ?? property.Name; .Value.Value as string ?? property.Name;
return sourceProperties.SingleOrDefault(p => p.Name == propertyName); return sourceProperties.FirstOrDefault(p => p.Name == propertyName);
} }
protected abstract ImmutableArray<MappedMember> GetSourceMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass); protected abstract ImmutableArray<MappedMember> GetSourceMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass);
@ -131,8 +135,12 @@ namespace MapTo
protected abstract ImmutableArray<MappedMember> GetTypeMappedFields(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass); protected abstract ImmutableArray<MappedMember> GetTypeMappedFields(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass);
protected ImmutableArray<INamedTypeSymbol> GetSourceTypeSymbol(TypeDeclarationSyntax typeDeclarationSyntax, SemanticModel? semanticModel = null) => protected ImmutableArray<INamedTypeSymbol> GetSourceTypeSymbol(TypeDeclarationSyntax typeDeclarationSyntax, SemanticModel? semanticModel = null)
GetSourceTypeSymbol(typeDeclarationSyntax.GetAttribute(MapFromAttributeSource.AttributeName), semanticModel); {
var attributeData = typeDeclarationSyntax.GetAttribute(MapFromAttributeSource.AttributeName);
var sourceSymbol = GetSourceTypeSymbol(attributeData, semanticModel);
return sourceSymbol;
}
// we need two possible InamedTypeSymbol // we need two possible InamedTypeSymbol
protected ImmutableArray<INamedTypeSymbol> GetSourceTypeSymbol(SyntaxNode? attributeSyntax, SemanticModel? semanticModel = null) protected ImmutableArray<INamedTypeSymbol> GetSourceTypeSymbol(SyntaxNode? attributeSyntax, SemanticModel? semanticModel = null)
@ -143,8 +151,10 @@ namespace MapTo
} }
semanticModel ??= Compilation.GetSemanticModel(attributeSyntax.SyntaxTree); semanticModel ??= Compilation.GetSemanticModel(attributeSyntax.SyntaxTree);
var sourceTypeExpressionSyntax = attributeSyntax var descendentNodes = attributeSyntax
.DescendantNodes() .DescendantNodes();
var sourceTypeExpressionSyntax = descendentNodes
.OfType<TypeOfExpressionSyntax>() .OfType<TypeOfExpressionSyntax>()
.ToImmutableArray(); .ToImmutableArray();
@ -503,8 +513,8 @@ namespace MapTo
var typeIdentifierName = TypeSyntax.GetIdentifierName(); var typeIdentifierName = TypeSyntax.GetIdentifierName();
var sourceTypeIdentifierName = sourceTypeSymbol.Name; var sourceTypeIdentifierName = sourceTypeSymbol.Name;
var isTypeInheritFromMappedBaseClass = IsTypeInheritFromMappedBaseClass(semanticModel); var isTypeInheritFromMappedBaseClass = IsTypeInheritFromMappedBaseClass(semanticModel);
var isTypeUpdatable = IsTypeUpdatable(); var isTypeUpdatable = false; //IsTypeUpdatable();
var hasJsonExtension = HasJsonExtension(); var hasJsonExtension = false; // HasJsonExtension();
var shouldGenerateSecondaryConstructor = ShouldGenerateSecondaryConstructor(semanticModel, sourceTypeSymbol); var shouldGenerateSecondaryConstructor = ShouldGenerateSecondaryConstructor(semanticModel, sourceTypeSymbol);
var mappedProperties = GetSourceMappedProperties(typeSymbol, sourceTypeSymbol, isTypeInheritFromMappedBaseClass); var mappedProperties = GetSourceMappedProperties(typeSymbol, sourceTypeSymbol, isTypeInheritFromMappedBaseClass);
@ -551,7 +561,7 @@ namespace MapTo
} }
return converterTypeSymbol.AllInterfaces return converterTypeSymbol.AllInterfaces
.SingleOrDefault(i => .FirstOrDefault(i =>
i.TypeArguments.Length == 2 && i.TypeArguments.Length == 2 &&
SymbolEqualityComparer.Default.Equals(i.ConstructedFrom, TypeConverterInterfaceTypeSymbol) && SymbolEqualityComparer.Default.Equals(i.ConstructedFrom, TypeConverterInterfaceTypeSymbol) &&
SymbolEqualityComparer.Default.Equals(sourceProperty.Type, i.TypeArguments[0]) && SymbolEqualityComparer.Default.Equals(sourceProperty.Type, i.TypeArguments[0]) &&
@ -565,7 +575,7 @@ namespace MapTo
} }
return converterTypeSymbol.AllInterfaces return converterTypeSymbol.AllInterfaces
.SingleOrDefault(i => .FirstOrDefault(i =>
i.TypeArguments.Length == 2 && i.TypeArguments.Length == 2 &&
SymbolEqualityComparer.Default.Equals(i.ConstructedFrom, TypeConverterInterfaceTypeSymbol) && SymbolEqualityComparer.Default.Equals(i.ConstructedFrom, TypeConverterInterfaceTypeSymbol) &&
SymbolEqualityComparer.Default.Equals(sourceProperty.Type, i.TypeArguments[0]) && SymbolEqualityComparer.Default.Equals(sourceProperty.Type, i.TypeArguments[0]) &&
@ -576,7 +586,7 @@ namespace MapTo
{ {
var constructorSyntax = TypeSyntax.DescendantNodes() var constructorSyntax = TypeSyntax.DescendantNodes()
.OfType<ConstructorDeclarationSyntax>() .OfType<ConstructorDeclarationSyntax>()
.SingleOrDefault(c => .FirstOrDefault(c =>
c.ParameterList.Parameters.Count == 1 && c.ParameterList.Parameters.Count == 1 &&
SymbolEqualityComparer.Default.Equals(semanticModel.GetTypeInfo(c.ParameterList.Parameters.Single().Type!).ConvertedType, sourceTypeSymbol)); SymbolEqualityComparer.Default.Equals(semanticModel.GetTypeInfo(c.ParameterList.Parameters.Single().Type!).ConvertedType, sourceTypeSymbol));

View File

@ -42,6 +42,13 @@ namespace MapTo.Sources
builder builder
.WriteLine($"public {AttributeName}Attribute(Type sourceType)") .WriteLine($"public {AttributeName}Attribute(Type sourceType)")
.WriteOpeningBracket() .WriteOpeningBracket()
.WriteLine("SourceType = new [] { sourceType };")
.WriteClosingBracket()
.WriteLine();
builder
.WriteLine($"public {AttributeName}Attribute(Type[] sourceType)")
.WriteOpeningBracket()
.WriteLine("SourceType = sourceType;") .WriteLine("SourceType = sourceType;")
.WriteClosingBracket() .WriteClosingBracket()
.WriteLine(); .WriteLine();
@ -55,7 +62,7 @@ namespace MapTo.Sources
} }
builder builder
.WriteLine("public Type SourceType { get; }") .WriteLine("public Type[] SourceType { get; }")
.WriteClosingBracket() // class .WriteClosingBracket() // class
.WriteClosingBracket(); // namespace .WriteClosingBracket(); // namespace

View File

@ -8,7 +8,7 @@ namespace MapTo.Tests.Extensions
internal static class RoslynExtensions internal static class RoslynExtensions
{ {
internal static SyntaxTree? GetGeneratedSyntaxTree(this Compilation compilation, string className) => internal static SyntaxTree? GetGeneratedSyntaxTree(this Compilation compilation, string className) =>
compilation.SyntaxTrees.SingleOrDefault(s => s.FilePath.EndsWith($"{className}.g.cs")); compilation.SyntaxTrees.FirstOrDefault(s => s.FilePath.EndsWith($"{className}.g.cs"));
internal static string PrintSyntaxTree(this Compilation compilation) internal static string PrintSyntaxTree(this Compilation compilation)
{ {

View File

@ -15,7 +15,7 @@ namespace MapTo.Tests.Extensions
{ {
var syntax = syntaxTree var syntax = syntaxTree
.Select(s => s.ToString().Trim()) .Select(s => s.ToString().Trim())
.SingleOrDefault(s => s.Contains(typeName)); .FirstOrDefault(s => s.Contains(typeName));
syntax.ShouldNotBeNullOrWhiteSpace(); syntax.ShouldNotBeNullOrWhiteSpace();
syntax.ShouldBe(expectedSource, customMessage); syntax.ShouldBe(expectedSource, customMessage);
@ -25,7 +25,7 @@ namespace MapTo.Tests.Extensions
{ {
var syntax = syntaxTree var syntax = syntaxTree
.Select(s => s.ToString().Trim()) .Select(s => s.ToString().Trim())
.SingleOrDefault(s => s.Contains(typeName)); .FirstOrDefault(s => s.Contains(typeName));
syntax.ShouldNotBeNullOrWhiteSpace(); syntax.ShouldNotBeNullOrWhiteSpace();
syntax.ShouldContainWithoutWhitespace(expectedSource, customMessage); syntax.ShouldContainWithoutWhitespace(expectedSource, customMessage);
@ -68,7 +68,7 @@ namespace MapTo.Tests.Extensions
internal static void ShouldNotBeSuccessful(this ImmutableArray<Diagnostic> diagnostics, Diagnostic expectedError) internal static void ShouldNotBeSuccessful(this ImmutableArray<Diagnostic> diagnostics, Diagnostic expectedError)
{ {
var actualDiagnostics = diagnostics.SingleOrDefault(d => d.Id == expectedError.Id); var actualDiagnostics = diagnostics.FirstOrDefault(d => d.Id == expectedError.Id);
var compilationDiagnostics = actualDiagnostics == null ? diagnostics : diagnostics.Except(new[] { actualDiagnostics }); var compilationDiagnostics = actualDiagnostics == null ? diagnostics : diagnostics.Except(new[] { actualDiagnostics });
compilationDiagnostics.ShouldBeSuccessful(); compilationDiagnostics.ShouldBeSuccessful();