diff --git a/BlueWest.Data/Finance/Currency/TestData.cs b/BlueWest.Data/Finance/Currency/TestData.cs
new file mode 100644
index 0000000..bef54d9
--- /dev/null
+++ b/BlueWest.Data/Finance/Currency/TestData.cs
@@ -0,0 +1,6 @@
+namespace BlueWest.Data;
+
+public class TestData
+{
+
+}
\ No newline at end of file
diff --git a/include/BlueWest.MapTo/src/BlueWest.MapTo/BlueWest.MapTo.csproj b/include/BlueWest.MapTo/src/BlueWest.MapTo/BlueWest.MapTo.csproj
index 6061e68..01debfe 100644
--- a/include/BlueWest.MapTo/src/BlueWest.MapTo/BlueWest.MapTo.csproj
+++ b/include/BlueWest.MapTo/src/BlueWest.MapTo/BlueWest.MapTo.csproj
@@ -18,6 +18,7 @@
bin\Release\MapTo.xml
+ false
diff --git a/include/BlueWest.MapTo/src/BlueWest.MapTo/Extensions/RoslynExtensions.cs b/include/BlueWest.MapTo/src/BlueWest.MapTo/Extensions/RoslynExtensions.cs
index 402996e..b38c6ff 100644
--- a/include/BlueWest.MapTo/src/BlueWest.MapTo/Extensions/RoslynExtensions.cs
+++ b/include/BlueWest.MapTo/src/BlueWest.MapTo/Extensions/RoslynExtensions.cs
@@ -33,11 +33,13 @@ namespace MapTo.Extensions
public static AttributeSyntax? GetAttribute(this TypeDeclarationSyntax typeDeclarationSyntax, string attributeName)
{
- return typeDeclarationSyntax.AttributeLists
- .SelectMany(al => al.Attributes)
- .SingleOrDefault(a =>
- (a.Name as IdentifierNameSyntax)?.Identifier.ValueText == attributeName ||
- ((a.Name as QualifiedNameSyntax)?.Right as IdentifierNameSyntax)?.Identifier.ValueText == attributeName);
+ var attributeLists = typeDeclarationSyntax.AttributeLists;
+ var selection = attributeLists
+ .SelectMany(al => al.Attributes);
+ var result = selection
+ .FirstOrDefault();
+
+ return result;
}
public static bool HasAttribute(this ISymbol symbol, ITypeSymbol attributeSymbol) =>
@@ -86,7 +88,7 @@ namespace MapTo.Extensions
public static IPropertySymbol? FindProperty(this IEnumerable properties, IPropertySymbol targetProperty)
{
- return properties.SingleOrDefault(p =>
+ return properties.FirstOrDefault(p =>
p.Name == targetProperty.Name &&
(p.NullableAnnotation != NullableAnnotation.Annotated ||
p.NullableAnnotation == NullableAnnotation.Annotated &&
diff --git a/include/BlueWest.MapTo/src/BlueWest.MapTo/MapToSyntaxReceiver.cs b/include/BlueWest.MapTo/src/BlueWest.MapTo/MapToSyntaxReceiver.cs
index 03c35ac..786f9ad 100644
--- a/include/BlueWest.MapTo/src/BlueWest.MapTo/MapToSyntaxReceiver.cs
+++ b/include/BlueWest.MapTo/src/BlueWest.MapTo/MapToSyntaxReceiver.cs
@@ -20,7 +20,7 @@ namespace MapTo
var attributeSyntax = attributes
.SelectMany(a => a.Attributes)
- .SingleOrDefault(a => a.Name is
+ .FirstOrDefault(a => a.Name is
IdentifierNameSyntax { Identifier: { ValueText: MapFromAttributeSource.AttributeName } } // For: [MapFrom]
or
QualifiedNameSyntax // For: [MapTo.MapFrom]
diff --git a/include/BlueWest.MapTo/src/BlueWest.MapTo/MappingContext.cs b/include/BlueWest.MapTo/src/BlueWest.MapTo/MappingContext.cs
index 37cc076..2f762f4 100644
--- a/include/BlueWest.MapTo/src/BlueWest.MapTo/MappingContext.cs
+++ b/include/BlueWest.MapTo/src/BlueWest.MapTo/MappingContext.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
+using System.Diagnostics;
using System.Linq;
+using System.Threading;
using MapTo.Extensions;
using MapTo.Sources;
using Microsoft.CodeAnalysis;
@@ -70,6 +72,8 @@ namespace MapTo
public static MappingContext Create(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
{
+ //SpinWait.SpinUntil(() => Debugger.IsAttached);
+
MappingContext context = typeSyntax switch
{
StructDeclarationSyntax => new StructMappingContext(compilation, sourceGenerationOptions, typeSyntax),
@@ -107,20 +111,20 @@ namespace MapTo
var propertyName = property
.GetAttribute(MapPropertyAttributeTypeSymbol)
?.NamedArguments
- .SingleOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName)
+ .FirstOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName)
.Value.Value as string ?? property.Name;
- return sourceProperties.SingleOrDefault(p => p.Name == propertyName);
+ return sourceProperties.FirstOrDefault(p => p.Name == propertyName);
}
protected IFieldSymbol? FindSourceField(IEnumerable sourceProperties, ISymbol property)
{
var propertyName = property
.GetAttribute(MapPropertyAttributeTypeSymbol)
?.NamedArguments
- .SingleOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName)
+ .FirstOrDefault(a => a.Key == MapPropertyAttributeSource.SourcePropertyNamePropertyName)
.Value.Value as string ?? property.Name;
- return sourceProperties.SingleOrDefault(p => p.Name == propertyName);
+ return sourceProperties.FirstOrDefault(p => p.Name == propertyName);
}
protected abstract ImmutableArray GetSourceMappedProperties(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass);
@@ -131,8 +135,12 @@ namespace MapTo
protected abstract ImmutableArray GetTypeMappedFields(ITypeSymbol typeSymbol, ITypeSymbol sourceTypeSymbol, bool isInheritFromMappedBaseClass);
- protected ImmutableArray GetSourceTypeSymbol(TypeDeclarationSyntax typeDeclarationSyntax, SemanticModel? semanticModel = null) =>
- GetSourceTypeSymbol(typeDeclarationSyntax.GetAttribute(MapFromAttributeSource.AttributeName), semanticModel);
+ protected ImmutableArray GetSourceTypeSymbol(TypeDeclarationSyntax typeDeclarationSyntax, SemanticModel? semanticModel = null)
+ {
+ var attributeData = typeDeclarationSyntax.GetAttribute(MapFromAttributeSource.AttributeName);
+ var sourceSymbol = GetSourceTypeSymbol(attributeData, semanticModel);
+ return sourceSymbol;
+ }
// we need two possible InamedTypeSymbol
protected ImmutableArray GetSourceTypeSymbol(SyntaxNode? attributeSyntax, SemanticModel? semanticModel = null)
@@ -143,11 +151,13 @@ namespace MapTo
}
semanticModel ??= Compilation.GetSemanticModel(attributeSyntax.SyntaxTree);
- var sourceTypeExpressionSyntax = attributeSyntax
- .DescendantNodes()
+ var descendentNodes = attributeSyntax
+ .DescendantNodes();
+
+ var sourceTypeExpressionSyntax = descendentNodes
.OfType()
.ToImmutableArray();
-
+
// cast
var resultList = new List();
for (int i = 0; i < sourceTypeExpressionSyntax.Length; i++)
@@ -503,8 +513,8 @@ namespace MapTo
var typeIdentifierName = TypeSyntax.GetIdentifierName();
var sourceTypeIdentifierName = sourceTypeSymbol.Name;
var isTypeInheritFromMappedBaseClass = IsTypeInheritFromMappedBaseClass(semanticModel);
- var isTypeUpdatable = IsTypeUpdatable();
- var hasJsonExtension = HasJsonExtension();
+ var isTypeUpdatable = false; //IsTypeUpdatable();
+ var hasJsonExtension = false; // HasJsonExtension();
var shouldGenerateSecondaryConstructor = ShouldGenerateSecondaryConstructor(semanticModel, sourceTypeSymbol);
var mappedProperties = GetSourceMappedProperties(typeSymbol, sourceTypeSymbol, isTypeInheritFromMappedBaseClass);
@@ -551,7 +561,7 @@ namespace MapTo
}
return converterTypeSymbol.AllInterfaces
- .SingleOrDefault(i =>
+ .FirstOrDefault(i =>
i.TypeArguments.Length == 2 &&
SymbolEqualityComparer.Default.Equals(i.ConstructedFrom, TypeConverterInterfaceTypeSymbol) &&
SymbolEqualityComparer.Default.Equals(sourceProperty.Type, i.TypeArguments[0]) &&
@@ -565,7 +575,7 @@ namespace MapTo
}
return converterTypeSymbol.AllInterfaces
- .SingleOrDefault(i =>
+ .FirstOrDefault(i =>
i.TypeArguments.Length == 2 &&
SymbolEqualityComparer.Default.Equals(i.ConstructedFrom, TypeConverterInterfaceTypeSymbol) &&
SymbolEqualityComparer.Default.Equals(sourceProperty.Type, i.TypeArguments[0]) &&
@@ -576,7 +586,7 @@ namespace MapTo
{
var constructorSyntax = TypeSyntax.DescendantNodes()
.OfType()
- .SingleOrDefault(c =>
+ .FirstOrDefault(c =>
c.ParameterList.Parameters.Count == 1 &&
SymbolEqualityComparer.Default.Equals(semanticModel.GetTypeInfo(c.ParameterList.Parameters.Single().Type!).ConvertedType, sourceTypeSymbol));
diff --git a/include/BlueWest.MapTo/src/BlueWest.MapTo/Sources/MapFromAttributeSource.cs b/include/BlueWest.MapTo/src/BlueWest.MapTo/Sources/MapFromAttributeSource.cs
index 70c48ef..e944025 100644
--- a/include/BlueWest.MapTo/src/BlueWest.MapTo/Sources/MapFromAttributeSource.cs
+++ b/include/BlueWest.MapTo/src/BlueWest.MapTo/Sources/MapFromAttributeSource.cs
@@ -42,6 +42,13 @@ namespace MapTo.Sources
builder
.WriteLine($"public {AttributeName}Attribute(Type sourceType)")
.WriteOpeningBracket()
+ .WriteLine("SourceType = new [] { sourceType };")
+ .WriteClosingBracket()
+ .WriteLine();
+
+ builder
+ .WriteLine($"public {AttributeName}Attribute(Type[] sourceType)")
+ .WriteOpeningBracket()
.WriteLine("SourceType = sourceType;")
.WriteClosingBracket()
.WriteLine();
@@ -55,7 +62,7 @@ namespace MapTo.Sources
}
builder
- .WriteLine("public Type SourceType { get; }")
+ .WriteLine("public Type[] SourceType { get; }")
.WriteClosingBracket() // class
.WriteClosingBracket(); // namespace
diff --git a/include/BlueWest.MapTo/test/BlueWest.MapTo.Tests/Extensions/RoslynExtensions.cs b/include/BlueWest.MapTo/test/BlueWest.MapTo.Tests/Extensions/RoslynExtensions.cs
index cddafeb..b9f81d4 100644
--- a/include/BlueWest.MapTo/test/BlueWest.MapTo.Tests/Extensions/RoslynExtensions.cs
+++ b/include/BlueWest.MapTo/test/BlueWest.MapTo.Tests/Extensions/RoslynExtensions.cs
@@ -8,7 +8,7 @@ namespace MapTo.Tests.Extensions
internal static class RoslynExtensions
{
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)
{
diff --git a/include/BlueWest.MapTo/test/BlueWest.MapTo.Tests/Extensions/ShouldlyExtensions.cs b/include/BlueWest.MapTo/test/BlueWest.MapTo.Tests/Extensions/ShouldlyExtensions.cs
index 2b9dd87..5aeee7c 100644
--- a/include/BlueWest.MapTo/test/BlueWest.MapTo.Tests/Extensions/ShouldlyExtensions.cs
+++ b/include/BlueWest.MapTo/test/BlueWest.MapTo.Tests/Extensions/ShouldlyExtensions.cs
@@ -15,7 +15,7 @@ namespace MapTo.Tests.Extensions
{
var syntax = syntaxTree
.Select(s => s.ToString().Trim())
- .SingleOrDefault(s => s.Contains(typeName));
+ .FirstOrDefault(s => s.Contains(typeName));
syntax.ShouldNotBeNullOrWhiteSpace();
syntax.ShouldBe(expectedSource, customMessage);
@@ -25,7 +25,7 @@ namespace MapTo.Tests.Extensions
{
var syntax = syntaxTree
.Select(s => s.ToString().Trim())
- .SingleOrDefault(s => s.Contains(typeName));
+ .FirstOrDefault(s => s.Contains(typeName));
syntax.ShouldNotBeNullOrWhiteSpace();
syntax.ShouldContainWithoutWhitespace(expectedSource, customMessage);
@@ -68,7 +68,7 @@ namespace MapTo.Tests.Extensions
internal static void ShouldNotBeSuccessful(this ImmutableArray 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 });
compilationDiagnostics.ShouldBeSuccessful();