Compiling state (replace SingleOrDefault by firstOrDefault)
This commit is contained in:
parent
7ba619240c
commit
6768e12bb1
|
@ -0,0 +1,6 @@
|
||||||
|
namespace BlueWest.Data;
|
||||||
|
|
||||||
|
public class TestData
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -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>
|
||||||
|
|
|
@ -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 &&
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue