Skip to content
Closed
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
5 changes: 3 additions & 2 deletions src/ChibiRuby.Serializer/Resolvers/GeneratedResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ static Cache()

static bool TryInvokeRegisterFormatter(Type type)
{
if (type.GetCustomAttribute<MRubyObjectAttribute>() == null) return false;

// Do not gate on [MRubyObject] here: Unity 6000.5+'s linker strips instances of
// PreserveAttribute-derived attributes from player builds, so the attribute can be
// absent at runtime even for generated types. The generated method is the reliable signal.
var m = type.GetMethod("__RegisterMRubyValueFormatter",
BindingFlags.Public |
BindingFlags.NonPublic |
Expand Down
21 changes: 21 additions & 0 deletions tests/ChibiRuby.Serializer.Tests/Classes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,24 @@ partial struct Struct1
{
public long Id { get; set; }
}

// Simulates a source-generated [MRubyObject] type after Unity 6000.5's linker has stripped the
// attribute instance (#199): the generated registration method exists, but the attribute does not.
class AttributeStrippedObject
{
public int Value { get; set; }

public static void __RegisterMRubyValueFormatter()
{
GeneratedResolver.Register(new AttributeStrippedObjectFormatter());
}

class AttributeStrippedObjectFormatter : IMRubyValueFormatter<AttributeStrippedObject?>
{
public MRubyValue Serialize(AttributeStrippedObject? value, MRubyState mrb, MRubyValueSerializerOptions options)
=> value is null ? default : new MRubyValue(value.Value);

public AttributeStrippedObject? Deserialize(MRubyValue value, MRubyState mrb, MRubyValueSerializerOptions options)
=> new() { Value = checked((int)value.IntegerValue) };
}
}
12 changes: 12 additions & 0 deletions tests/ChibiRuby.Serializer.Tests/GeneratedFormatterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,16 @@ public void DeserializeWithCtor()
Assert.That(result.Y, Is.EqualTo(456));
Assert.That(result.Hoge, Is.EqualTo("hello hello"));
}

[Test]
public void RegisterFormatterWithoutAttributeInstance()
{
// The [MRubyObject] attribute instance may be stripped by Unity 6000.5+'s linker (#199).
// Registration must work based on the generated method alone.
var result = MRubyValueSerializer.Deserialize<AttributeStrippedObject>(new MRubyValue(42), state)!;
Assert.That(result.Value, Is.EqualTo(42));

var serialized = MRubyValueSerializer.Serialize(new AttributeStrippedObject { Value = 43 }, state);
Assert.That(serialized, Is.EqualTo(new MRubyValue(43)));
}
}
Loading