Skip to content

Commit

Permalink
Merge pull request #57 from Methuselah96/fix-attribute-copying
Browse files Browse the repository at this point in the history
Fix crash when copying custom attributes with array constructor arguments
  • Loading branch information
jbtule authored Nov 16, 2024
2 parents 174a6d5 + e5aaf2e commit 5e70e34
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 6 deletions.
35 changes: 30 additions & 5 deletions ImpromptuInterface/src/EmitProxy/ActLikeMaker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1433,11 +1433,36 @@ public static CustomAttributeBuilder ToCustomAttributeBuilder(CustomAttributeDat
{
return new CustomAttributeBuilder(
customAttributeData.Constructor,
customAttributeData.ConstructorArguments.Select(arg => arg.Value).ToArray(),
customAttributeData.NamedArguments.Where(arg => arg.MemberInfo.MemberType == MemberTypes.Property).Select(arg => arg.MemberInfo).Cast<PropertyInfo>().ToArray(),
customAttributeData.NamedArguments.Where(arg => arg.MemberInfo.MemberType == MemberTypes.Property).Select(arg => arg.TypedValue.Value).ToArray(),
customAttributeData.NamedArguments.Where(arg => arg.MemberInfo.MemberType == MemberTypes.Field).Select(arg => arg.MemberInfo).Cast<FieldInfo>().ToArray(),
customAttributeData.NamedArguments.Where(arg => arg.MemberInfo.MemberType == MemberTypes.Field).Select(arg => arg.TypedValue.Value).ToArray());
customAttributeData.ConstructorArguments
.Select(
arg =>
arg.Value?.GetType()
== typeof(ReadOnlyCollection<CustomAttributeTypedArgument>)
? ((ReadOnlyCollection<CustomAttributeTypedArgument>)arg.Value)
.Select(arrayArg => arrayArg.Value)
.ToArray()
: arg.Value
)
.ToArray(),
customAttributeData.NamedArguments
.Where(arg => arg.MemberInfo.MemberType == MemberTypes.Property)
.Select(arg => arg.MemberInfo)
.Cast<PropertyInfo>()
.ToArray(),
customAttributeData.NamedArguments
.Where(arg => arg.MemberInfo.MemberType == MemberTypes.Property)
.Select(arg => arg.TypedValue.Value)
.ToArray(),
customAttributeData.NamedArguments
.Where(arg => arg.MemberInfo.MemberType == MemberTypes.Field)
.Select(arg => arg.MemberInfo)
.Cast<FieldInfo>()
.ToArray(),
customAttributeData.NamedArguments
.Where(arg => arg.MemberInfo.MemberType == MemberTypes.Field)
.Select(arg => arg.TypedValue.Value)
.ToArray()
);
}


Expand Down
30 changes: 29 additions & 1 deletion Tests/UnitTestImpromptuInterface/Basic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -444,11 +444,30 @@ public void PropertyAttributeTest()
{
dynamic tNew = new ExpandoObject();
ISimpeleSetClassProps tActsLike = Impromptu.ActLike<ISimpeleSetClassProps>(tNew);
var attribute = (DisplayNameAttribute)tActsLike.GetType().GetProperty(nameof(ISimpeleSetClassProps.Prop1)).GetCustomAttribute(typeof(DisplayNameAttribute), true);
var attribute = (DisplayNameAttribute)
tActsLike
.GetType()
.GetProperty(nameof(ISimpeleSetClassProps.Prop1))
.GetCustomAttribute(typeof(DisplayNameAttribute), true);
Assert.NotNull(attribute);
Assert.AreEqual("testDisplayName", attribute.DisplayName);
}

[Test]
public void PropertyAttributeWithArrayArgumentTest()
{
dynamic tNew = new ExpandoObject();
ISimpeleSetClassProps tActsLike = Impromptu.ActLike<ISimpeleSetClassProps>(tNew);
var attribute = (DisplayNamesAttribute)
tActsLike
.GetType()
.GetProperty(nameof(ISimpeleSetClassProps.Prop2))
.GetCustomAttribute(typeof(DisplayNamesAttribute), true);
Assert.NotNull(attribute);
Assert.AreEqual("testDisplayName1", attribute.DisplayNames[0]);
Assert.AreEqual("testDisplayName2", attribute.DisplayNames[1]);
}

[Test]
public void EventDynamicPropertyTest()
{
Expand Down Expand Up @@ -654,6 +673,15 @@ public void RefMethodTest()
Assert.AreEqual(true, tOut);
Assert.AreEqual(4, tResult2);
}

[Test]
public void GenericStructInNullableContextTest()
{
var result = new
{
SomeOtherProperty = "test"
}.ActLike<IInterfaceWithGenericStructProperty>();
}
}
}

34 changes: 34 additions & 0 deletions Tests/UnitTestImpromptuInterface/Support/SupportDefinitions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,22 @@ public interface ISimpeleClassProps
Guid Prop3 { get; }
}

public class DisplayNamesAttribute : Attribute
{
public string[] DisplayNames { get; }

public DisplayNamesAttribute(params string[] displayNames)
{
DisplayNames = displayNames;
}
}

public interface ISimpeleSetClassProps
{
[DisplayName("testDisplayName")]
string Prop1 { set ; }

[DisplayNames("testDisplayName1", "testDisplayName2")]
long Prop2 { set; }

Guid Prop3 { set; }
Expand Down Expand Up @@ -577,4 +588,27 @@ public bool IsFixedSize
}
}

#if NET6_0_OR_GREATER
#nullable enable
#endif
public struct GenericStruct<T>
{
public string Something { get; }

public GenericStruct(string something)
{
Something = something;
}
}

public interface IInterfaceWithGenericStructProperty
{
GenericStruct<IInterfaceWithGenericStructProperty> StructProperty { get; }

string SomeOtherProperty { get; }
}
#if NET6_0_OR_GREATER
#nullable restore
#endif

}

0 comments on commit 5e70e34

Please sign in to comment.