Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v2.0.6 #99

Merged
merged 3 commits into from Dec 5, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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;
}
}
}