Skip to content

Commit

Permalink
Merge pull request #99 from RicoSuter/master
Browse files Browse the repository at this point in the history
Release v2.0.6
  • Loading branch information
RicoSuter committed Dec 5, 2021
2 parents b302b6b + 75cc01f commit 05ebafa
Show file tree
Hide file tree
Showing 18 changed files with 221 additions and 92 deletions.
3 changes: 1 addition & 2 deletions README.md
Expand Up @@ -4,9 +4,8 @@

[![Azure DevOps](https://img.shields.io/azure-devops/build/rsuter/Namotion/16/master.svg)](https://dev.azure.com/rsuter/Namotion/_build?definitionId=16)
[![Azure DevOps](https://img.shields.io/azure-devops/coverage/rsuter/Namotion/16/master.svg)](https://dev.azure.com/rsuter/Namotion/_build?definitionId=16)
[![Nuget](https://img.shields.io/nuget/v/Namotion.Reflection.svg)](https://www.nuget.org/packages/Namotion.Reflection/)
[![Nuget](https://img.shields.io/nuget/v/Namotion.Reflection.svg)](https://apimundo.com/organizations/nuget-org/nuget-feeds/public/packages/Namotion.Reflection/versions/latest)
[![MyGet](https://img.shields.io/myget/namotion-reflection/v/Namotion.Reflection.svg?label=preview%20nuget)](https://www.myget.org/feed/Packages/namotion-reflection)
[![Apimundo](https://img.shields.io/badge/Namotion.Reflection%20API-Apimundo-728199.svg)](https://apimundo.com/organizations/nuget-org/nuget-feeds/public/packages/Namotion.Reflection/versions/latest?tab=types)

<img align="left" src="https://raw.githubusercontent.com/RicoSuter/Namotion.Reflection/master/assets/Icon.png" width="48px" height="48px">

Expand Down
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Expand Up @@ -20,7 +20,7 @@ steps:
displayName: 'Install .NET Core SDK'
inputs:
packageType: 'sdk'
version: '5.0.102'
version: '6.0.100'

# Patch preview project versions (only when on master branch)
- task: CmdLine@2
Expand Down
@@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>9</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.10.14" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NBench" Version="1.0.4" />
<PackageReference Include="Pro.NBench.xUnit" Version="1.0.4" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>
Expand Down
@@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>9</LangVersion>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Mono.Cecil" Version="0.10.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>
<ItemGroup>
Expand Down
Expand Up @@ -6,7 +6,7 @@
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>../Namotion.Reflection.snk</AssemblyOriginatorKeyFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Version>2.0.5</Version>
<Version>2.0.6</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageIconUrl>https://raw.githubusercontent.com/RicoSuter/Namotion.Reflection/master/assets/NuGetIcon.png</PackageIconUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
@@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>9.0</LangVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NJsonSchema" Version="10.1.5" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>
<ItemGroup>
Expand Down
9 changes: 6 additions & 3 deletions src/Namotion.Reflection/Context/ContextualFieldInfo.cs
Expand Up @@ -14,15 +14,18 @@ public class ContextualFieldInfo : ContextualAccessorInfo
internal ContextualFieldInfo(FieldInfo fieldInfo, ref int nullableFlagsIndex, byte[]? nullableFlags)
{
FieldInfo = fieldInfo;

var attributeProviders = fieldInfo.DeclaringType.IsNested
? new [] { NullableFlagsSource.Create(fieldInfo.DeclaringType), NullableFlagsSource.Create(fieldInfo.DeclaringType.DeclaringType, fieldInfo.DeclaringType.GetTypeInfo().Assembly) }
: new [] { NullableFlagsSource.Create(fieldInfo.DeclaringType, fieldInfo.DeclaringType.GetTypeInfo().Assembly) };

FieldType = new ContextualType(
fieldInfo.FieldType,
fieldInfo.GetCustomAttributes(true).OfType<Attribute>().ToArray(),
null,
ref nullableFlagsIndex,
nullableFlags,
fieldInfo.DeclaringType.IsNested ?
new dynamic[] { fieldInfo.DeclaringType, fieldInfo.DeclaringType.DeclaringType, fieldInfo.DeclaringType.GetTypeInfo().Assembly } :
new dynamic[] { fieldInfo.DeclaringType, fieldInfo.DeclaringType.GetTypeInfo().Assembly });
attributeProviders);
}

/// <summary>
Expand Down
15 changes: 11 additions & 4 deletions src/Namotion.Reflection/Context/ContextualParameterInfo.cs
Expand Up @@ -14,9 +14,9 @@ public class ContextualParameterInfo : ContextualType
internal ContextualParameterInfo(ParameterInfo parameterInfo, ref int nullableFlagsIndex, byte[]? nullableFlags)
: base(parameterInfo.ParameterType, GetContextualAttributes(parameterInfo),
null, ref nullableFlagsIndex, nullableFlags,
parameterInfo.Member.DeclaringType.IsNested ?
new dynamic[] { parameterInfo.Member, parameterInfo.Member.DeclaringType, parameterInfo.Member.DeclaringType.DeclaringType, parameterInfo.Member.DeclaringType.GetTypeInfo().Assembly } :
new dynamic[] { parameterInfo.Member, parameterInfo.Member.DeclaringType, parameterInfo.Member.DeclaringType.GetTypeInfo().Assembly })
parameterInfo.Member.DeclaringType.IsNested
? new[] { NullableFlagsSource.Create(parameterInfo.Member), NullableFlagsSource.Create(parameterInfo.Member.DeclaringType), NullableFlagsSource.Create(parameterInfo.Member.DeclaringType.DeclaringType, parameterInfo.Member.DeclaringType.GetTypeInfo().Assembly) }
: new[] { NullableFlagsSource.Create(parameterInfo.Member), NullableFlagsSource.Create(parameterInfo.Member.DeclaringType, parameterInfo.Member.DeclaringType.GetTypeInfo().Assembly) })
{
ParameterInfo = parameterInfo;
}
Expand All @@ -41,7 +41,14 @@ private static Attribute[] GetContextualAttributes(ParameterInfo parameterInfo)
{
try
{
return parameterInfo.GetCustomAttributes(true).OfType<Attribute>().ToArray();
var attributes = parameterInfo.GetCustomAttributes(true);
#if !NETSTANDARD1_0
if (attributes.Length == 0)
{
return ArrayExt.Empty<Attribute>();
}
#endif
return attributes.OfType<Attribute>().ToArray();
}
catch
{
Expand Down
13 changes: 8 additions & 5 deletions src/Namotion.Reflection/Context/ContextualPropertyInfo.cs
Expand Up @@ -17,15 +17,18 @@ public class ContextualPropertyInfo : ContextualAccessorInfo
internal ContextualPropertyInfo(PropertyInfo propertyInfo, ref int nullableFlagsIndex, byte[]? nullableFlags)
{
PropertyInfo = propertyInfo;

var attributeProviders = propertyInfo.DeclaringType.IsNested
? new [] { NullableFlagsSource.Create(propertyInfo.DeclaringType), NullableFlagsSource.Create(propertyInfo.DeclaringType.DeclaringType, propertyInfo.DeclaringType.GetTypeInfo().Assembly) }
: new [] { NullableFlagsSource.Create(propertyInfo.DeclaringType, propertyInfo.DeclaringType.GetTypeInfo().Assembly) };

PropertyType = new ContextualType(
propertyInfo.PropertyType,
propertyInfo.GetCustomAttributes(true).OfType<Attribute>().ToArray(),
null,
ref nullableFlagsIndex,
null,
ref nullableFlagsIndex,
nullableFlags,
propertyInfo.DeclaringType.IsNested ?
new dynamic[] { propertyInfo.DeclaringType, propertyInfo.DeclaringType.DeclaringType, propertyInfo.DeclaringType.GetTypeInfo().Assembly } :
new dynamic[] { propertyInfo.DeclaringType, propertyInfo.DeclaringType.GetTypeInfo().Assembly });
attributeProviders);
}

/// <summary>
Expand Down
59 changes: 29 additions & 30 deletions src/Namotion.Reflection/Context/ContextualType.cs
Expand Up @@ -11,6 +11,8 @@ namespace Namotion.Reflection
/// </summary>
public class ContextualType : CachedType
{
private static readonly byte[] _emptyNullableFlags = { 0 };

private readonly int _nullableFlagsIndex;
private byte[]? _nullableFlags;
private Nullability? nullability;
Expand All @@ -27,13 +29,12 @@ internal static ContextualType ForType(Type type, IEnumerable<Attribute> context
}

internal ContextualType(Type type, IEnumerable<Attribute> contextAttributes, ContextualType? parent,
ref int nullableFlagsIndex, byte[]? nullableFlags, IEnumerable<dynamic>? customAttributeProviders)
ref int nullableFlagsIndex, byte[]? nullableFlags, NullableFlagsSource[] customAttributeProviders)
: base(type)
{
Parent = parent;
ContextAttributes = contextAttributes is Attribute[] attributesArray ?
attributesArray : contextAttributes?.ToArray() ??
new Attribute[0];
attributesArray : contextAttributes?.ToArray() ?? ArrayExt.Empty<Attribute>();

_nullableFlags = nullableFlags;
_nullableFlagsIndex = nullableFlagsIndex;
Expand Down Expand Up @@ -418,7 +419,7 @@ protected override CachedType GetCachedType(Type type, ref int nullableFlagsInde
return new ContextualType(type, ContextAttributes, this, ref nullableFlagsIndex, _nullableFlags, null);
}

private void InitializeNullableFlagsAndOriginalNullability(ref int nullableFlagsIndex, IEnumerable<dynamic>? customAttributeProviders)
private void InitializeNullableFlagsAndOriginalNullability(ref int nullableFlagsIndex, NullableFlagsSource[] customAttributeProviders)
{
var typeInfo = OriginalType.GetTypeInfo();
try
Expand All @@ -435,16 +436,20 @@ private void InitializeNullableFlagsAndOriginalNullability(ref int nullableFlags
if (typeInfo.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint) || // specifically a struct - existing code works
typeInfo.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint)) // specifically a class - existing code works
{
nullableAttribute = typeInfo.GetCustomAttributes().FirstOrDefault(a => a.GetType().FullName == "System.Runtime.CompilerServices.NullableAttribute");
if (nullableAttribute is not null)
{
_nullableFlags = GetFlagsFromNullableAttribute(nullableAttribute);
}
else
{
// Default nullability (NullableContextAttribute) from the context
_nullableFlags = GetFlagsFromCustomAttributeProviders(typeInfo.DeclaringType.IsNested ? new dynamic[] { typeInfo.DeclaringType, typeInfo.DeclaringType.DeclaringType } : new dynamic[] { typeInfo.DeclaringType });
}
nullableAttribute = typeInfo.GetCustomAttributes().FirstOrDefault(a => a.GetType().FullName == "System.Runtime.CompilerServices.NullableAttribute");
if (nullableAttribute is not null)
{
_nullableFlags = GetFlagsFromNullableAttribute(nullableAttribute);
}
else
{
// Default nullability (NullableContextAttribute) from the context
var attributeProviders = typeInfo.DeclaringType.IsNested
? new[] { NullableFlagsSource.Create(typeInfo.DeclaringType), NullableFlagsSource.Create(typeInfo.DeclaringType.DeclaringType) }
: new[] { NullableFlagsSource.Create(typeInfo.DeclaringType) };

_nullableFlags = GetFlagsFromCustomAttributeProviders(attributeProviders);
}
}
else
{
Expand All @@ -455,7 +460,7 @@ private void InitializeNullableFlagsAndOriginalNullability(ref int nullableFlags
}
else
{
_nullableFlags = new byte[] { 0 }; // Unknown
_nullableFlags = _emptyNullableFlags; // Unknown
}
}

Expand All @@ -467,13 +472,13 @@ private void InitializeNullableFlagsAndOriginalNullability(ref int nullableFlags
}
else
{
_nullableFlags = new byte[] { 0 }; // Unknown
_nullableFlags = _emptyNullableFlags; // Unknown
}
}
}
catch
{
_nullableFlags = new byte[] { 0 };
_nullableFlags = _emptyNullableFlags;
#if DEBUG
throw;
#endif
Expand Down Expand Up @@ -503,30 +508,24 @@ private void InitializeNullableFlagsAndOriginalNullability(ref int nullableFlags
private byte[] GetFlagsFromNullableAttribute(Attribute nullableAttribute)
{
#if NET40
return (byte[]?)nullableAttribute?.GetType().GetField("NullableFlags")?.GetValue(nullableAttribute) ?? new byte[0];
return (byte[]?)nullableAttribute?.GetType().GetField("NullableFlags")?.GetValue(nullableAttribute) ?? _emptyNullableFlags;
#else
return (byte[]?)nullableAttribute?.GetType().GetRuntimeField("NullableFlags")?.GetValue(nullableAttribute) ?? new byte[] { 0 };
return (byte[]?)nullableAttribute?.GetType().GetRuntimeField("NullableFlags")?.GetValue(nullableAttribute) ??_emptyNullableFlags;
#endif
}

private byte[] GetFlagsFromCustomAttributeProviders(IEnumerable<dynamic> customAttributeProviders)
private static byte[]? GetFlagsFromCustomAttributeProviders(NullableFlagsSource[] customAttributeProviders)
{
foreach (var provider in customAttributeProviders)
{
var attributes = (IEnumerable<object>)provider.GetCustomAttributes(false);
var nullableContextAttribute = attributes.FirstOrDefault(a => a.GetType().FullName == "System.Runtime.CompilerServices.NullableContextAttribute");
if (nullableContextAttribute != null)
var flags = provider.NullableFlags;
if (flags is not null)
{
#if NET40
return new byte[] { (byte)nullableContextAttribute.GetType().GetField("Flag").GetValue(nullableContextAttribute) };
#else
return new byte[] { (byte)nullableContextAttribute.GetType().GetRuntimeField("Flag").GetValue(nullableContextAttribute) };
#endif
return flags;
}
}

return new byte[] { 0 };

return _emptyNullableFlags;
}
}
}

0 comments on commit 05ebafa

Please sign in to comment.