Skip to content

Commit

Permalink
Post implementation tidy up
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveDunn committed Nov 13, 2024
1 parent acd8d74 commit f3c7ae8
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 116 deletions.
8 changes: 8 additions & 0 deletions src/Vogen/ConversionMarkerKind.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Vogen;

public enum ConversionMarkerKind
{
Unrecognized,
EFCore,
MessagePack,
}
46 changes: 25 additions & 21 deletions src/Vogen/ConversionMarkers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ public static IEnumerable<AttributeData> TryGetMarkerAttributes(INamedTypeSymbol
a => _knownMarkerAttributes.ContainsKey(a.AttributeClass?.MetadataName ?? ""));
}

public static MarkerClassDefinition? GetConversionMarkerClassDefinitionFromAttribute(GeneratorSyntaxContext context)
public static MarkerClassDefinition? GetConversionMarkerClassesFromAttribute(GeneratorSyntaxContext context)
{
// var voSyntaxInformation = (TypeDeclarationSyntax) context.Node;

var semanticModel = context.SemanticModel;

ISymbol declaredSymbol = semanticModel.GetDeclaredSymbol(context.Node)!;
Expand All @@ -50,9 +48,8 @@ public static IEnumerable<AttributeData> TryGetMarkerAttributes(INamedTypeSymbol

public static bool IsTarget(SyntaxNode node) =>
node is TypeDeclarationSyntax { AttributeLists.Count: > 0 };


public static MarkerAttributeDefinition? TryBuild(AttributeData markerAtt, in INamedTypeSymbol? markerClassSymbol)

private static MarkerAttributeDefinition? TryBuild(AttributeData markerAtt, in INamedTypeSymbol? markerClassSymbol)
{
ImmutableArray<TypedConstant> args = markerAtt.ConstructorArguments;

Expand All @@ -64,54 +61,61 @@ public static bool IsTarget(SyntaxNode node) =>
return null;
}

if (markerAtt.AttributeClass == null)
if (markerAtt.AttributeClass?.TypeArguments.SingleOrDefaultIfMultiple() is not INamedTypeSymbol voSymbol)
{
return null;
}

var voSymbol = markerAtt.AttributeClass.TypeArguments.SingleOrDefaultIfMultiple() as INamedTypeSymbol;
ConversionMarkerKind markerKind = ResolveMarkerKind(markerAtt);

if (voSymbol is null)
if(markerKind is ConversionMarkerKind.Unrecognized)
{
return null;
}

ConversionMarkerKind markerKind = ResolveMarkerKind(markerAtt);

if(markerKind is ConversionMarkerKind.Unrecognized) return null;

if (!VoFilter.IsTarget(voSymbol))
{
// return ConversionMarkerAttributeDefinition.Error(markerKind, DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(markerClassSymbol!, voSymbol));
return MarkerAttributeDefinition.Error(DiagnosticsCatalogue.TypesReferencedInAConversionMarkerMustBeaValueObjects(markerClassSymbol!, voSymbol));
return MarkerAttributeDefinition.Error(
DiagnosticsCatalogue.TypesReferencedInAConversionMarkerMustBeaValueObjects(markerClassSymbol!, voSymbol));
}

List<AttributeData> voAttributes = VoFilter.TryGetValueObjectAttributes(voSymbol).ToList();

if(voAttributes.Count != 1) return null;
if(voAttributes.Count != 1)
{
return null;
}

AttributeData voAttribute = voAttributes[0];

VogenConfigurationBuildResult config = BuildConfigurationFromAttributes.TryBuildFromValueObjectAttribute(voAttribute);

if(config.HasDiagnostics) return null;
if(config.HasDiagnostics)
{
return null;
}

VogenConfiguration c = config.ResultingConfiguration!;

var underlyingType = c.UnderlyingType ?? ResolveUnderlyingType(voSymbol);
var underlyingType = c.UnderlyingType ?? TryResolveUnderlyingType(voSymbol);

if (underlyingType is null)
{
return MarkerAttributeDefinition.Error(DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(markerClassSymbol!, voSymbol, markerAtt.ApplicationSyntaxReference?.GetSyntax().GetLocation()));
return MarkerAttributeDefinition.Error(
DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(
markerClassSymbol!,
voSymbol,
markerAtt.ApplicationSyntaxReference?.GetSyntax().GetLocation()));
}

return MarkerAttributeDefinition.Ok(markerKind, voSymbol, underlyingType, markerClassSymbol!);
}

private static ConversionMarkerKind ResolveMarkerKind(AttributeData att) =>
// ReSharper disable once CanSimplifyDictionaryTryGetValueWithGetValueOrDefault
_knownMarkerAttributes.TryGetValue(att.AttributeClass?.MetadataName ?? "", out var kind) ? kind : ConversionMarkerKind.Unrecognized;

private static INamedTypeSymbol? ResolveUnderlyingType(INamedTypeSymbol method)
private static INamedTypeSymbol? TryResolveUnderlyingType(INamedTypeSymbol method)
{
ImmutableArray<ISymbol> ms = method.GetMembers("Value");

Expand All @@ -122,6 +126,6 @@ private static ConversionMarkerKind ResolveMarkerKind(AttributeData att) =>

IPropertySymbol? prop = ms[0] as IPropertySymbol;

return (INamedTypeSymbol)prop!.Type;
return prop!.Type as INamedTypeSymbol;
}
}
1 change: 0 additions & 1 deletion src/Vogen/Diagnostics/RuleIdentifiers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public static class RuleIdentifiers
public const string IncorrectUseOfInstanceField = "VOG027";
public const string IncorrectUseOfNormalizeInputMethod = "VOG028";
public const string ExplicitlySpecifyTypeInValueObjectAttribute = "VOG029";
//public const string EfCoreTargetMustExplicitlySpecifyItsPrimitive = "VOG030";
public const string TypesReferencedInAConversionMarkerMustBeaValueObjects = "VOG031";
public const string DoNotThrowFromUserCode = "VOG032";
public const string UseReadonlyStructInsteadOfStruct = "VOG033";
Expand Down
7 changes: 2 additions & 5 deletions src/Vogen/GenerateCodeForEfCoreMarkers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ private static void WriteEachIfNeeded(SourceProductionContext context, Conversio

SourceText sourceText = SourceText.From(sb, Encoding.UTF8);

string filename = Util.GetLegalMarkerClassFilename(markerClass.MarkerClassSymbol, markerClass.VoSymbol, markerClass.Kind);
string filename = Util.GetLegalFilenameForMarkerClass(markerClass.MarkerClassSymbol, markerClass.VoSymbol, markerClass.Kind);

Util.TryWriteUsingUniqueFilename(filename, context, sourceText);
}
Expand Down Expand Up @@ -120,9 +120,7 @@ private static void StoreExtensionMethodToRegisterAllInMarkerClass(

SourceText sourceText = SourceText.From(source, Encoding.UTF8);

var filename = Util.GetLegalMarkerClassFilename(markerSymbol, ConversionMarkerKind.EFCore);

//string filename = Util.SanitizeToALegalFilename($"{markerSymbol.ToDisplayString()}.g.cs");
var filename = Util.GetLegalFilenameForMarkerClass(markerSymbol, ConversionMarkerKind.EFCore);

Util.TryWriteUsingUniqueFilename(filename, context, sourceText);

Expand All @@ -146,5 +144,4 @@ string GenerateBody()
return sb.ToString();
}
}

}
49 changes: 38 additions & 11 deletions src/Vogen/GenerateCodeForMessagePack.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
Expand All @@ -9,7 +10,15 @@ namespace Vogen;

internal class GenerateCodeForMessagePack
{
public static void GenerateForAMarkerClass(SourceProductionContext context, MarkerClassDefinition markerClass)
public static void GenerateForMarkerClasses(SourceProductionContext context, ImmutableArray<MarkerClassDefinition> conversionMarkerClasses)
{
foreach (MarkerClassDefinition? eachMarkerClass in conversionMarkerClasses)
{
GenerateCodeForMessagePack.GenerateForAMarkerClass(context, eachMarkerClass);
}
}

private static void GenerateForAMarkerClass(SourceProductionContext context, MarkerClassDefinition markerClass)
{
var markerClassSymbol = markerClass.MarkerClassSymbol;

Expand Down Expand Up @@ -41,7 +50,7 @@ public static void GenerateForAMarkerClass(SourceProductionContext context, Mark

SourceText sourceText = Util.FormatSource(s);

string filename = Util.GetLegalMarkerClassFilename(markerClass.MarkerClassSymbol, ConversionMarkerKind.MessagePack);
string filename = Util.GetLegalFilenameForMarkerClass(markerClass.MarkerClassSymbol, ConversionMarkerKind.MessagePack);

Util.TryWriteUsingUniqueFilename(filename, context, sourceText);

Expand All @@ -63,9 +72,11 @@ string GenerateEach()
m => m.Marker?.Kind is ConversionMarkerKind.MessagePack).Select(
x =>
{
//if (x is null) return null;
if (x.Marker is null) return null;
if (x.Marker is null)
{
return null;
}
string wrapperNameShort = x.Marker.VoSymbol.Name;
return $"new {wrapperNameShort}MessagePackFormatter()";
Expand Down Expand Up @@ -139,7 +150,6 @@ private static FormatterSourceAndFilename GenerateSourceAndFilename(string acces
return new FormatterSourceAndFilename(filename, sb);
}


private static string GenerateSource(string accessibility,
INamedTypeSymbol wrapperSymbol,
INamedTypeSymbol underlyingSymbol)
Expand All @@ -151,11 +161,6 @@ private static string GenerateSource(string accessibility,

string underlyingTypeName = underlyingSymbol.FullName() ?? underlyingSymbol.Name;

// if (readAndWriteMethods.Item1.Length == 0)
// {
// return $"#error unsupported underlying type '{underlyingSymbol.FullName()}' for value object '{wrapperSymbol.Name}' - you need to turn off MessagePack support for this value object and provide your own resolver";
// }

string nativeReadMethod = TryGetNativeReadMethod(underlyingSymbol);

if (!string.IsNullOrEmpty(nativeReadMethod))
Expand Down Expand Up @@ -224,4 +229,26 @@ private static string TryGetNativeReadMethod(INamedTypeSymbol primitive) =>
SpecialType.System_UInt64 => "ReadUInt64()",
_ => ""
};

/// <summary>
/// Represents a marker for a MessagePack conversion
/// </summary>
/// <param name="ContainerNamespace">The namespace of the containing marker class.</param>
/// <param name="WrapperType">The symbol for the value object wrapper class.</param>
/// <param name="UnderlyingType">The symbol for the underlying primitive type.</param>
/// <param name="WrapperAccessibility">The accessibility (public, internal, etc.) of the generated type.</param>
private record MessagePackStandalone(
string ContainerNamespace,
INamedTypeSymbol WrapperType,
INamedTypeSymbol UnderlyingType,
string WrapperAccessibility)
{
public static MessagePackStandalone FromWorkItem(VoWorkItem voWorkItem)
{
var isPublic = voWorkItem.WrapperType.DeclaredAccessibility.HasFlag(Accessibility.Public);
var accessor = isPublic ? "public" : "internal";

return new(voWorkItem.FullNamespace, voWorkItem.WrapperType, voWorkItem.UnderlyingType, accessor);
}
}
}
18 changes: 0 additions & 18 deletions src/Vogen/GenerateCodeForMessagePackMarkers.cs

This file was deleted.

8 changes: 3 additions & 5 deletions src/Vogen/GenerateCodeForToString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ private static string GenerateAnyHoistedToStringMethods(GenerationParameters gen
{
List<IMethodSymbol> methodsToWrite = FilterOutUserSuppliedMethods(
item.ToStringInformation.ToStringMethodsOnThePrimitive,
item.UserProvidedOverloads.ToStringOverloads,
item).ToList();
item.UserProvidedOverloads.ToStringOverloads).ToList();

StringBuilder sb = new StringBuilder();

Expand Down Expand Up @@ -66,12 +65,11 @@ private static string GenerateAnyHoistedToStringMethods(GenerationParameters gen
// or the wrapper.
static IEnumerable<IMethodSymbol> FilterOutUserSuppliedMethods(
List<IMethodSymbol> methodsOnThePrimitive,
UserProvidedToStringMethods methodsOnTheWrapper,
VoWorkItem vo)
UserProvidedToStringMethods methodsOnTheWrapper)
{
foreach (var eachMethod in methodsOnThePrimitive)
{
if (!methodsOnTheWrapper.Contains(eachMethod, vo))
if (!methodsOnTheWrapper.Contains(eachMethod))
{
yield return eachMethod;
}
Expand Down
1 change: 1 addition & 0 deletions src/Vogen/Generators/Conversions/IGenerateConversion.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
// ReSharper disable UnusedParameter.Global

namespace Vogen.Generators.Conversions;

Expand Down
49 changes: 0 additions & 49 deletions src/Vogen/MarkerAttribute2.cs

This file was deleted.

3 changes: 1 addition & 2 deletions src/Vogen/UserProvidedToStringMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ public class UserProvidedToStringMethods : IEnumerable<IMethodSymbol>
/// Sees if the items held contains the method from the primitive.
/// </summary>
/// <param name="methodFromPrimitive"></param>
/// <param name="vo"></param>
/// <returns></returns>
public bool Contains(IMethodSymbol methodFromPrimitive, VoWorkItem vo)
public bool Contains(IMethodSymbol methodFromPrimitive)
{
foreach (var eachUserMethod in _userMethods)
{
Expand Down
8 changes: 4 additions & 4 deletions src/Vogen/ValueObjectGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)

var targetsAndConfig = collectedVos.Combine(found.GlobalConfig.Collect());

var targetsConfigAndConversionMarkers = targetsAndConfig.Combine(found.ConverterMarkerClasses.Collect());
var targetsConfigAndMarkers = targetsAndConfig.Combine(found.ConverterMarkerClasses.Collect());

var compilationAndValues = context.CompilationProvider.Combine(targetsConfigAndConversionMarkers);
var compilationAndValues = context.CompilationProvider.Combine(targetsConfigAndMarkers);

var everything = compilationAndValues.Combine(knownSymbols);

Expand Down Expand Up @@ -71,7 +71,7 @@ private static Found GetTargets(SyntaxValueProvider syntaxProvider)

IncrementalValuesProvider<MarkerClassDefinition> converterMarkerClasses = syntaxProvider.CreateSyntaxProvider(
predicate: (node, _) => ConversionMarkers.IsTarget(node),
transform: (ctx, _) => ConversionMarkers.GetConversionMarkerClassDefinitionFromAttribute(ctx))
transform: (ctx, _) => ConversionMarkers.GetConversionMarkerClassesFromAttribute(ctx))
.Where(static m => m is not null)!;

return new Found(targets, globalConfig, converterMarkerClasses);
Expand Down Expand Up @@ -129,7 +129,7 @@ private static void Execute(
// the user can specify to create the MessagePack generated code as an attribute
// or as marker in another project.
GenerateCodeForMessagePack.GenerateForApplicableValueObjects(spc, compilation, workItems);
GenerateCodeForMessagePackMarkers.GenerateForMarkerClasses(spc, compilation, markerClasses, vogenKnownSymbols);
GenerateCodeForMessagePack.GenerateForMarkerClasses(spc, markerClasses);

GenerateCodeForBsonSerializers.WriteIfNeeded(spc, compilation, workItems);

Expand Down

0 comments on commit f3c7ae8

Please sign in to comment.