Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,17 @@ public static bool TryCreate(INamedTypeSymbol type, [NotNullWhen(true)] out Cust
CodeAnalysisUtilities.FindInaccessibleTypes(type).Any() ? MsgPack00xMessagePackAnalyzer.InaccessibleFormatterType :
instanceProvidingMember is null ? MsgPack00xMessagePackAnalyzer.InaccessibleFormatterInstance :
null,
ExcludeFromSourceGeneratedResolver =
type.GetAttributes().Any(a => a.AttributeClass?.Name == Constants.ExcludeFormatterFromSourceGeneratedResolverAttributeName && a.AttributeClass?.ContainingNamespace.Name == Constants.AttributeNamespace),
};

return true;
}

public DiagnosticDescriptor? InaccessibleDescriptor { get; init; }

public bool ExcludeFromSourceGeneratedResolver { get; init; }

public virtual bool Equals(CustomFormatter other)
{
return this.Name.Equals(other.Name)
Expand Down
4 changes: 3 additions & 1 deletion src/MessagePack.SourceGenerator/MessagePackGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
predicate: static (node, ct) => node is ClassDeclarationSyntax { BaseList.Types.Count: > 0 },
transform: (ctxt, ct) =>
{
return ctxt.SemanticModel.GetDeclaredSymbol(ctxt.Node, ct) is INamedTypeSymbol symbol && CustomFormatter.TryCreate(symbol, out CustomFormatter? formatter)
return ctxt.SemanticModel.GetDeclaredSymbol(ctxt.Node, ct) is INamedTypeSymbol symbol
&& CustomFormatter.TryCreate(symbol, out CustomFormatter? formatter)
&& !formatter.ExcludeFromSourceGeneratedResolver
? formatter
: null;
}).Collect();
Expand Down
1 change: 1 addition & 0 deletions src/MessagePack.SourceGenerator/Utils/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ internal static class Constants
internal const string CompositeResolverAttributeName = "CompositeResolverAttribute";
internal const string GeneratedMessagePackResolverAttributeName = "GeneratedMessagePackResolverAttribute";
internal const string MessagePackKnownFormatterAttributeName = "MessagePackKnownFormatterAttribute";
internal const string ExcludeFormatterFromSourceGeneratedResolverAttributeName = "ExcludeFormatterFromSourceGeneratedResolverAttribute";
internal const string MessagePackAssumedFormattableAttributeName = "MessagePackAssumedFormattableAttribute";
internal const string MessagePackObjectAttributeName = "MessagePackObjectAttribute";
internal const string MessagePackUnionAttributeName = "UnionAttribute";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,18 @@ public MessagePackAssumedFormattableAttribute(Type formattableType)
/// </summary>
public Type FormattableType { get; }
}

/// <summary>
/// Causes the source generated resolver, which typically includes all implementations of <c>IMessagePackFormatter&lt;T&gt;</c>,
/// to exclude this particular formatter.
/// </summary>
/// <remarks>
/// This is useful when the formatter is intended for special case members,
/// which may apply the <see cref="MessagePackFormatterAttribute"/> to select the private formatter.
/// </remarks>
[AttributeUsage(AttributeTargets.Class)]
[Conditional("NEVERDEFINED")]
public class ExcludeFormatterFromSourceGeneratedResolverAttribute : Attribute
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using MessagePack.Formatters;

public class ExcludedCustomFormatter
{
[Fact]
public void ExcludedFormatterIsIgnored()
{
// This would normally succeed because of our custom formatter and the auto-generated resolver,
// but because of the attribute applied to the formatter, it should not be included in the resolver,
// and thus our custom type should fail to serialize as an unknown type.
Assert.Throws<MessagePackSerializationException>(
() => MessagePackSerializer.Serialize(default(CustomType), MessagePackSerializerOptions.Standard));
}

internal struct CustomType;

[ExcludeFormatterFromSourceGeneratedResolver]
internal class CustomFormatter : IMessagePackFormatter<CustomType>
{
public CustomType Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
reader.Skip();
return default;
}

public void Serialize(ref MessagePackWriter writer, CustomType value, MessagePackSerializerOptions options)
{
writer.WriteNil();
}
}
}
18 changes: 18 additions & 0 deletions tests/MessagePack.SourceGenerator.Tests/GenerationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -545,4 +545,22 @@ public void Serialize(ref MessagePackWriter writer, A value, MessagePackSerializ
""";
await VerifyCS.Test.RunDefaultAsync(this.testOutputHelper, testSource);
}

[Fact]
public async Task ExcludeFormatterFromSourceGeneratedResolver()
{
string testSource = """
using MessagePack;
using MessagePack.Formatters;
class A {}
[ExcludeFormatterFromSourceGeneratedResolver]
class F : IMessagePackFormatter<A> {
public void Serialize(ref MessagePackWriter writer, A value, MessagePackSerializerOptions options) {}
public A Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) => default;
}
""";

// This test is *not* expected to produce any generated files.
await VerifyCS.Test.RunDefaultAsync(this.testOutputHelper, testSource);
}
}