提交 d54e6469 编写于 作者: S Sam Harwell

Handle missing private metadata from reference assemblies

Some reference assemblies omit information about private fields. To
avoid treating structures in these assemblies as immutable, we only
consider types immutable if they contain information about one or more
private fields.

This is a workaround for issues like dotnet/standard#678.
上级 0b8e89e9
......@@ -5,6 +5,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
......@@ -894,6 +895,34 @@ public static bool IsEnumType(this ITypeSymbol type)
type = type.GetTypeArguments()[0];
}
switch (type.SpecialType)
{
case SpecialType.System_Boolean:
case SpecialType.System_Char:
case SpecialType.System_SByte:
case SpecialType.System_Byte:
case SpecialType.System_Int16:
case SpecialType.System_UInt16:
case SpecialType.System_Int32:
case SpecialType.System_UInt32:
case SpecialType.System_Int64:
case SpecialType.System_UInt64:
case SpecialType.System_Decimal:
case SpecialType.System_Single:
case SpecialType.System_Double:
return false;
case SpecialType.System_IntPtr:
case SpecialType.System_UIntPtr:
return false;
case SpecialType.System_DateTime:
return false;
default:
break;
}
if (type.IsErrorType())
{
return null;
......@@ -904,15 +933,35 @@ public static bool IsEnumType(this ITypeSymbol type)
return false;
}
var hasPrivateField = false;
foreach (var member in type.GetMembers())
{
if (member is IFieldSymbol fieldSymbol &&
!(fieldSymbol.IsConst || fieldSymbol.IsReadOnly || fieldSymbol.IsStatic))
if (!(member is IFieldSymbol fieldSymbol))
{
continue;
}
hasPrivateField |= fieldSymbol.DeclaredAccessibility == Accessibility.Private;
if (!fieldSymbol.IsConst && !fieldSymbol.IsReadOnly && !fieldSymbol.IsStatic)
{
return true;
}
}
if (!hasPrivateField)
{
// Some reference assemblies omit information about private fields. If we can't be sure the field is
// immutable, treat it as potentially mutable.
foreach (var attributeData in type.ContainingAssembly.GetAttributes())
{
if (attributeData.AttributeClass.Name == nameof(ReferenceAssemblyAttribute)
&& attributeData.AttributeClass.ToNameDisplayString() == typeof(ReferenceAssemblyAttribute).FullName)
{
return null;
}
}
}
return false;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册