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
1 change: 1 addition & 0 deletions source/nanoFramework.CoreLibrary/CoreLibrary.nfproj
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
<Compile Include="System\Reflection\Binder.cs" />
<Compile Include="System\Reflection\BindingFlags.cs" />
<Compile Include="System\Reflection\ConstructorInfo.cs" />
<Compile Include="System\Reflection\CustomAttributesHelpers.cs" />
<Compile Include="System\Reflection\DefaultMemberAttribute.cs" />
<Compile Include="System\Reflection\FieldInfo.cs" />
<Compile Include="System\Reflection\FieldReflectionAttributes.cs" />
Expand Down
2 changes: 1 addition & 1 deletion source/nanoFramework.CoreLibrary/System/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
[assembly: AssemblyProduct("nanoFramework mscorlib")]
[assembly: AssemblyCopyright("Copyright © nanoFramework Contributors 2017")]

[assembly: AssemblyNativeVersion("100.4.7.0")]
[assembly: AssemblyNativeVersion("100.4.8.0")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// Copyright (c) 2020 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

namespace System.Reflection
{
internal class CustomAttributesHelpers
{
public static object[] GetCustomAttributesInternal(object[] rawAttributes)
{
// get the custom attributes data for the field
// these are returned "encoded" in an object array with 2 positions for each attribute
// 1st the attribute type
// 2nd the constructor parameter or null, if the attribute has no constructor
//
// current limitations:
// - works only for constructors with a single parameter
// - the parameter has to be a string or numeric type
//
// both limitations above can be relatively easily overcome by adding the appropriate code at the native handler

object[] attributes = new object[rawAttributes.Length / 2];

for (int i = 0; i < rawAttributes.Length; i += 2)
{
// peek next element to determine if it's null
if (rawAttributes[i + 1] == null)
{
// attribute without default constructor, just copy it
attributes[i / 2] = rawAttributes[i];
}
else
{
// has default constructor, invoke it

// get the types
Type objectType = rawAttributes[i].GetType();
Type paramType = rawAttributes[i + 1].GetType();

// get constructor
ConstructorInfo ctor = objectType.GetConstructor(new Type[] { paramType });

// invoke constructor with the parameter
attributes[i / 2] = ctor.Invoke(new object[] { rawAttributes[i + 1] });
}
}

return attributes;
}
}
}
40 changes: 1 addition & 39 deletions source/nanoFramework.CoreLibrary/System/Reflection/FieldInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,45 +73,7 @@ public abstract Type FieldType
/// <remarks>This method ignores the inherit parameter for properties and events.</remarks>
public override object[] GetCustomAttributes(bool inherit)
{
// get the custom attributes data for the field
// these are returned "encoded" in an object array with 2 positions for each attribute
// 1st the attribute type
// 2nd the constructor parameter or null, if the attribute has no constructor
//
// current limitations:
// - works only for constructors with a single parameter
// - the parameter has to be a string or numeric type
//
// both limitations above can be relatively easily overcome by adding the appropriate code at the native handler
var ret = GetCustomAttributesNative(inherit);

object[] attributes = new object[ ret.Length/2 ];

for (int i = 0; i < ret.Length; i += 2)
{
// peek next element to determine if it's null
if(ret[ i+1 ] == null)
{
// attribute without default constructor, just copy it
attributes[ i/2 ] = ret[i];
}
else
{
// has default constructor, invoke it

// get the types
Type objectType = ret[i].GetType();
Type paramType = ret[ i+1 ].GetType();

// get constructor
ConstructorInfo ctor = objectType.GetConstructor(new Type[] { paramType });

// invoke constructor with the parameter
attributes[ i/2 ] = ctor.Invoke(new object[] { ret[ i+1 ] });
}
}

return attributes;
return CustomAttributesHelpers.GetCustomAttributesInternal(GetCustomAttributesNative(inherit));
}

[MethodImpl(MethodImplOptions.InternalCall)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,16 @@ public override extern Type ReturnType
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}


public override object[] GetCustomAttributes(bool inherit)
{
return CustomAttributesHelpers.GetCustomAttributesInternal(GetCustomAttributesNative(inherit));
}

[MethodImpl(MethodImplOptions.InternalCall)]
public override extern object[] GetCustomAttributes(bool inherit);
#pragma warning disable S4200 // Native methods should be wrapped
private extern object[] GetCustomAttributesNative(bool inherit);
#pragma warning restore S4200 // Native methods should be wrapped
}
}

Expand Down
9 changes: 8 additions & 1 deletion source/nanoFramework.CoreLibrary/System/RuntimeType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,15 @@ public override extern Type BaseType
[MethodImpl(MethodImplOptions.InternalCall)]
public override extern Type GetElementType();

public override object[] GetCustomAttributes(bool inherit)
{
return CustomAttributesHelpers.GetCustomAttributesInternal(GetCustomAttributesNative(inherit));
}

[MethodImpl(MethodImplOptions.InternalCall)]
public override extern object[] GetCustomAttributes(bool inherit);
#pragma warning disable S4200 // Native methods should be wrapped
private extern object[] GetCustomAttributesNative(bool inherit);
#pragma warning restore S4200 // Native methods should be wrapped
}
}

Expand Down