未验证 提交 467c216f 编写于 作者: A Abhitej John 提交者: GitHub

Merge pull request #24890 from dotnet/merges/dev15.7.x-to-master

Merge dev15.7.x to master
......@@ -138,6 +138,9 @@
<DeterministicSourceRoot Condition="'$(DeveloperBuild)' != 'true'">/_/</DeterministicSourceRoot>
<EnableSourceLink Condition="'$(DeveloperBuild)' != 'true'">true</EnableSourceLink>
<ChecksumAlgorithm>SHA256</ChecksumAlgorithm>
<EnableDefaultNoneItems>false</EnableDefaultNoneItems>
<!--
......
......@@ -440,14 +440,10 @@ public override ImmutableArray<CSharpAttributeData> GetAttributes()
if (FilterOutDecimalConstantAttribute())
{
// filter out DecimalConstantAttribute
CustomAttributeHandle ignore1;
CustomAttributeHandle ignore2;
var attributes = containingPEModuleSymbol.GetCustomAttributesForToken(
_handle,
out ignore1,
AttributeDescription.DecimalConstantAttribute,
out ignore2,
default(AttributeDescription));
out _,
AttributeDescription.DecimalConstantAttribute);
ImmutableInterlocked.InterlockedInitialize(ref _lazyCustomAttributes, attributes);
}
......
......@@ -20,7 +20,10 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE
/// </summary>
internal sealed class PEMethodSymbol : MethodSymbol
{
private class SignatureData
/// <summary>
/// internal for testing purpose
/// </summary>
internal class SignatureData
{
public readonly SignatureHeader Header;
public readonly ImmutableArray<ParameterSymbol> Parameters;
......@@ -555,7 +558,10 @@ private bool SetAssociatedPropertyOrEvent(Symbol propertyOrEventSymbol, MethodKi
return false;
}
private SignatureData Signature => _lazySignature ?? LoadSignature();
/// <summary>
/// internal for testing purpose
/// </summary>
internal SignatureData Signature => _lazySignature ?? LoadSignature();
private SignatureData LoadSignature()
{
......
......@@ -275,49 +275,64 @@ internal void LoadCustomAttributes(EntityHandle token, ref ImmutableArray<CSharp
ImmutableInterlocked.InterlockedInitialize(ref customAttributes, loadedCustomAttributes);
}
internal ImmutableArray<CSharpAttributeData> GetCustomAttributesForToken(EntityHandle token,
out CustomAttributeHandle filteredOutAttribute1,
AttributeDescription filterOut1)
{
return GetCustomAttributesForToken(token, out filteredOutAttribute1, filterOut1, out _, default, out _, default, out _, default);
}
/// <summary>
/// Returns a possibly ExtensionAttribute filtered roArray of attributes. If
/// filterExtensionAttributes is set to true, the method will remove all ExtensionAttributes
/// from the returned array. If it is false, the parameter foundExtension will always be set to
/// false and can be safely ignored.
///
/// The paramArrayAttribute parameter is similar to the foundExtension parameter, but instead
/// of just indicating if the attribute was found, the parameter is set to the attribute handle
/// for the ParamArrayAttribute if any is found and is null otherwise. This allows NoPia to filter
/// the attribute out for the symbol but still cache it separately for emit.
/// Returns attributes with up-to four filters applied. For each filter, the last application of the
/// attribute will be tracked and returned.
/// </summary>
internal ImmutableArray<CSharpAttributeData> GetCustomAttributesForToken(EntityHandle token,
out CustomAttributeHandle filteredOutAttribute1,
AttributeDescription filterOut1,
out CustomAttributeHandle filteredOutAttribute2,
AttributeDescription filterOut2)
{
filteredOutAttribute1 = default(CustomAttributeHandle);
filteredOutAttribute2 = default(CustomAttributeHandle);
AttributeDescription filterOut2,
out CustomAttributeHandle filteredOutAttribute3,
AttributeDescription filterOut3,
out CustomAttributeHandle filteredOutAttribute4,
AttributeDescription filterOut4)
{
filteredOutAttribute1 = default;
filteredOutAttribute2 = default;
filteredOutAttribute3 = default;
filteredOutAttribute4 = default;
ArrayBuilder<CSharpAttributeData> customAttributesBuilder = null;
try
{
foreach (var customAttributeHandle in _module.GetCustomAttributesOrThrow(token))
{
if (filterOut1.Signatures != null &&
Module.GetTargetAttributeSignatureIndex(customAttributeHandle, filterOut1) != -1)
// It is important to capture the last application of the attribute that we run into,
// it makes a difference for default and constant values.
if (matchesFilter(customAttributeHandle, filterOut1))
{
// It is important to capture the last application of the attribute that we run into,
// it makes a difference for default and constant values.
filteredOutAttribute1 = customAttributeHandle;
continue;
}
if (filterOut2.Signatures != null &&
Module.GetTargetAttributeSignatureIndex(customAttributeHandle, filterOut2) != -1)
if (matchesFilter(customAttributeHandle, filterOut2))
{
// It is important to capture the last application of the attribute that we run into,
// it makes a difference for default and constant values.
filteredOutAttribute2 = customAttributeHandle;
continue;
}
if (matchesFilter(customAttributeHandle, filterOut3))
{
filteredOutAttribute3 = customAttributeHandle;
continue;
}
if (matchesFilter(customAttributeHandle, filterOut4))
{
filteredOutAttribute4 = customAttributeHandle;
continue;
}
if (customAttributesBuilder == null)
{
customAttributesBuilder = ArrayBuilder<CSharpAttributeData>.GetInstance();
......@@ -335,18 +350,15 @@ internal void LoadCustomAttributes(EntityHandle token, ref ImmutableArray<CSharp
}
return ImmutableArray<CSharpAttributeData>.Empty;
bool matchesFilter(CustomAttributeHandle handle, AttributeDescription filter)
=> filter.Signatures != null && Module.GetTargetAttributeSignatureIndex(handle, filter) != -1;
}
internal ImmutableArray<CSharpAttributeData> GetCustomAttributesForToken(EntityHandle token)
{
// Do not filter anything and therefore ignore the out results
CustomAttributeHandle ignore1;
CustomAttributeHandle ignore2;
return GetCustomAttributesForToken(token,
out ignore1,
default(AttributeDescription),
out ignore2,
default(AttributeDescription));
return GetCustomAttributesForToken(token, out _, default);
}
/// <summary>
......@@ -358,13 +370,7 @@ internal ImmutableArray<CSharpAttributeData> GetCustomAttributesForToken(EntityH
internal ImmutableArray<CSharpAttributeData> GetCustomAttributesForToken(EntityHandle token,
out CustomAttributeHandle paramArrayAttribute)
{
CustomAttributeHandle ignore;
return GetCustomAttributesForToken(
token,
out paramArrayAttribute,
AttributeDescription.ParamArrayAttribute,
out ignore,
default(AttributeDescription));
return GetCustomAttributesForToken(token, out paramArrayAttribute, AttributeDescription.ParamArrayAttribute);
}
......@@ -403,12 +409,7 @@ internal TypeSymbol TryDecodeAttributeWithTypeArgument(EntityHandle handle, Attr
internal ImmutableArray<CSharpAttributeData> GetCustomAttributesFilterExtensions(EntityHandle token, out bool foundExtension)
{
CustomAttributeHandle extensionAttribute;
CustomAttributeHandle ignore;
var result = GetCustomAttributesForToken(token,
out extensionAttribute,
AttributeDescription.CaseSensitiveExtensionAttribute,
out ignore,
default(AttributeDescription));
var result = GetCustomAttributesForToken(token, out extensionAttribute, AttributeDescription.CaseSensitiveExtensionAttribute);
foundExtension = !extensionAttribute.IsNil;
return result;
......
......@@ -607,7 +607,13 @@ public override ImmutableArray<CSharpAttributeData> GetAttributes()
MightContainExtensionMethods ? AttributeDescription.CaseSensitiveExtensionAttribute : default,
out _,
// Filter out [Obsolete], unless it was user defined
(IsByRefLikeType && ObsoleteAttributeData is null) ? AttributeDescription.ObsoleteAttribute : default);
(IsByRefLikeType && ObsoleteAttributeData is null) ? AttributeDescription.ObsoleteAttribute : default,
out _,
// Filter out [IsReadOnly]
IsReadOnly ? AttributeDescription.IsReadOnlyAttribute : default,
out _,
// Filter out [IsByRefLike]
IsByRefLikeType ? AttributeDescription.IsByRefLikeAttribute : default);
ImmutableInterlocked.InterlockedInitialize(ref uncommon.lazyCustomAttributes, loadedCustomAttributes);
}
......
......@@ -326,7 +326,7 @@ private sealed class PEParameterSymbolWithCustomModifiers : PEParameterSymbol
ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers,
out bool isBad) :
base(moduleSymbol, containingSymbol, ordinal, isByRef, type, handle,
refCustomModifiers.NullToEmpty().Length + customModifiers.NullToEmpty().Length,
refCustomModifiers.NullToEmpty().Length + customModifiers.NullToEmpty().Length,
out isBad)
{
_customModifiers = CSharpCustomModifier.Convert(customModifiers);
......@@ -766,18 +766,25 @@ public override ImmutableArray<CSharpAttributeData> GetAttributes()
}
}
if (filterOutParamArrayAttribute || filterOutConstantAttributeDescription.Signatures != null)
bool filterIsReadOnlyAttribute = this.RefKind == RefKind.In;
if (filterOutParamArrayAttribute || filterOutConstantAttributeDescription.Signatures != null || filterIsReadOnlyAttribute)
{
CustomAttributeHandle paramArrayAttribute;
CustomAttributeHandle constantAttribute;
CustomAttributeHandle isReadOnlyAttribute;
ImmutableArray<CSharpAttributeData> attributes =
containingPEModuleSymbol.GetCustomAttributesForToken(
_handle,
out paramArrayAttribute,
filterOutParamArrayAttribute ? AttributeDescription.ParamArrayAttribute : default(AttributeDescription),
filterOutParamArrayAttribute ? AttributeDescription.ParamArrayAttribute : default,
out constantAttribute,
filterOutConstantAttributeDescription);
filterOutConstantAttributeDescription,
out isReadOnlyAttribute,
filterIsReadOnlyAttribute ? AttributeDescription.IsReadOnlyAttribute : default,
out _,
default);
if (!paramArrayAttribute.IsNil || !constantAttribute.IsNil)
{
......
......@@ -531,7 +531,13 @@ public override ImmutableArray<CSharpAttributeData> GetAttributes()
if (_lazyCustomAttributes.IsDefault)
{
var containingPEModuleSymbol = (PEModuleSymbol)this.ContainingModule;
containingPEModuleSymbol.LoadCustomAttributes(_handle, ref _lazyCustomAttributes);
ImmutableArray<CSharpAttributeData> attributes = containingPEModuleSymbol.GetCustomAttributesForToken(
_handle,
out _,
this.RefKind == RefKind.RefReadOnly ? AttributeDescription.IsReadOnlyAttribute : default);
ImmutableInterlocked.InterlockedInitialize(ref _lazyCustomAttributes, attributes);
}
return _lazyCustomAttributes;
}
......
......@@ -9478,7 +9478,7 @@ private static void PrivateMethod()
MetadataReaderUtils.VerifyPEMetadata(exe,
new[] { "TypeDefinition:<Module>", "TypeDefinition:C" },
new[] { "MethodDefinition:Void Main()", "MethodDefinition:Void PrivateMethod()", "MethodDefinition:Void .ctor()" },
new[] { "MethodDefinition:Void C.Main()", "MethodDefinition:Void C.PrivateMethod()", "MethodDefinition:Void C..ctor()" },
new[] { "CompilationRelaxationsAttribute", "RuntimeCompatibilityAttribute", "DebuggableAttribute" }
);
......@@ -9513,7 +9513,7 @@ private static void PrivateMethod()
// See issue https://github.com/dotnet/roslyn/issues/17612
MetadataReaderUtils.VerifyPEMetadata(refDll,
new[] { "TypeDefinition:<Module>", "TypeDefinition:C" },
new[] { "MethodDefinition:Void Main()", "MethodDefinition:Void .ctor()" },
new[] { "MethodDefinition:Void C.Main()", "MethodDefinition:Void C..ctor()" },
new[] { "CompilationRelaxationsAttribute", "RuntimeCompatibilityAttribute", "DebuggableAttribute", "ReferenceAssemblyAttribute" }
);
......@@ -9596,7 +9596,7 @@ private struct S
// See issue https://github.com/dotnet/roslyn/issues/17612
MetadataReaderUtils.VerifyPEMetadata(refDll,
new[] { "TypeDefinition:<Module>", "TypeDefinition:C", "TypeDefinition:S" },
new[] { "MethodDefinition:Void Main()", "MethodDefinition:Void .ctor()" },
new[] { "MethodDefinition:Void C.Main()", "MethodDefinition:Void C..ctor()" },
new[] { "CompilationRelaxationsAttribute", "RuntimeCompatibilityAttribute", "DebuggableAttribute", "ReferenceAssemblyAttribute" }
);
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.UnitTests;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using System.Collections.Immutable;
using System.Linq;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
......@@ -29,11 +31,17 @@ class Test
}
";
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
void validate(ModuleSymbol module)
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type, module.ContainingAssembly.Name);
});
AssertReferencedIsByRefLike(type);
var peModule = (PEModuleSymbol)module;
Assert.True(peModule.Module.HasIsByRefLikeAttribute(((PENamedTypeSymbol)type).Handle));
AssertDeclaresType(peModule, WellKnownType.System_Runtime_CompilerServices_IsByRefLikeAttribute, Accessibility.Public);
}
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: validate);
}
[Fact]
......@@ -46,7 +54,7 @@ public void IsByRefLikeIsWrittenToMetadata_NeedsToBeGenerated()
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("S1");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
AssertReferencedIsByRefLike(type);
});
}
......@@ -63,7 +71,7 @@ class Test
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
AssertReferencedIsByRefLike(type);
});
}
......@@ -77,11 +85,17 @@ class Test
}
";
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
void validate(ModuleSymbol module)
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test+S1`1");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
});
AssertReferencedIsByRefLike(type);
var peModule = (PEModuleSymbol)module;
Assert.True(peModule.Module.HasIsByRefLikeAttribute(((PENamedTypeSymbol)type).Handle));
AssertDeclaresType(peModule, WellKnownType.System_Runtime_CompilerServices_IsByRefLikeAttribute, Accessibility.Internal);
}
CompileAndVerify(text, symbolValidator: validate);
}
[Fact]
......@@ -97,7 +111,7 @@ class Test<T>
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test`1").GetTypeMember("S1");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
AssertReferencedIsByRefLike(type);
});
}
......@@ -123,7 +137,7 @@ class Test
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type, referenceA.Compilation.AssemblyName);
AssertReferencedIsByRefLike(type);
AssertNoIsByRefLikeAttributeExists(module.ContainingAssembly);
});
}
......@@ -417,7 +431,7 @@ public class Test
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type, reference.Display);
AssertReferencedIsByRefLike(type);
AssertNoIsByRefLikeAttributeExists(module.ContainingAssembly);
});
}
......@@ -567,7 +581,7 @@ public interface Test
var property = type.GetMember<PEPropertySymbol>("Property");
Assert.NotNull(property);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, property.Type, module.ContainingAssembly.Name);
AssertReferencedIsByRefLike(property.Type);
});
var code = @"
......@@ -640,27 +654,26 @@ class Test
}
";
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
void validate(ModuleSymbol module)
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
var accessibility = Accessibility.Public;
var attributes = type.GetAttributes();
Assert.Equal(2, attributes.Count());
var assemblyName = module.ContainingAssembly.Name;
var attributeType = attributes[0].AttributeClass;
Assert.Equal("System.Runtime.CompilerServices.IsByRefLikeAttribute", attributeType.ToDisplayString());
Assert.Equal(assemblyName, attributeType.ContainingAssembly.Name);
Assert.Equal(accessibility, attributeType.DeclaredAccessibility);
var attribute = attributes[1];
var attribute = type.GetAttributes().Single();
Assert.Equal("System.ObsoleteAttribute", attribute.AttributeClass.ToDisplayString());
Assert.Equal("hello", attribute.ConstructorArguments.ElementAt(0).Value);
Assert.Equal(true, attribute.ConstructorArguments.ElementAt(1).Value);
});
if (module is PEModuleSymbol peModule)
{
Assert.True(peModule.Module.HasIsByRefLikeAttribute(((PENamedTypeSymbol)type).Handle));
AssertDeclaresType(peModule, WellKnownType.System_Runtime_CompilerServices_IsByRefLikeAttribute, Accessibility.Public);
}
};
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: validate, sourceSymbolValidator: validate);
}
[Fact]
......@@ -686,7 +699,7 @@ public class ObsoleteAttribute{}
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type, module.ContainingAssembly.Name, hasObsolete: false);
AssertReferencedIsByRefLike(type, hasObsolete: false);
});
}
......@@ -730,18 +743,7 @@ class Test
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
var accessibility = Accessibility.Public;
var attributes = type.GetAttributes();
Assert.Equal(2, attributes.Count());
var assemblyName = module.ContainingAssembly.Name;
var attributeType = attributes[0].AttributeClass;
Assert.Equal("System.Runtime.CompilerServices.IsByRefLikeAttribute", attributeType.ToDisplayString());
Assert.Equal(assemblyName, attributeType.ContainingAssembly.Name);
Assert.Equal(accessibility, attributeType.DeclaredAccessibility);
var attribute = attributes[1];
var attribute = type.GetAttributes().Single();
Assert.Equal("Windows.Foundation.Metadata.DeprecatedAttribute", attribute.AttributeClass.ToDisplayString());
Assert.Equal(42u, attribute.ConstructorArguments.ElementAt(2).Value);
});
......@@ -788,20 +790,12 @@ class Test
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
var accessibility = Accessibility.Public;
var attributes = type.GetAttributes();
Assert.Equal(3, attributes.Length);
Assert.Equal("Windows.Foundation.Metadata.DeprecatedAttribute", attributes[2].AttributeClass.ToDisplayString());
var assemblyName = module.ContainingAssembly.Name;
var attributeType = attributes[0].AttributeClass;
Assert.Equal("System.Runtime.CompilerServices.IsByRefLikeAttribute", attributeType.ToDisplayString());
Assert.Equal(assemblyName, attributeType.ContainingAssembly.Name);
Assert.Equal(accessibility, attributeType.DeclaredAccessibility);
Assert.Equal(2, attributes.Length);
Assert.Equal("Windows.Foundation.Metadata.DeprecatedAttribute", attributes[1].AttributeClass.ToDisplayString());
var attribute = attributes[1];
var attribute = attributes[0];
Assert.Equal("System.ObsoleteAttribute", attribute.AttributeClass.ToDisplayString());
Assert.Equal(0, attribute.ConstructorArguments.Count());
});
......@@ -855,7 +849,7 @@ public void ObsoleteHasErrorEqualsTrue()
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("S");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
AssertReferencedIsByRefLike(type);
});
}
......@@ -962,17 +956,17 @@ public class ObsoleteAttribute: Attribute
CompileAndVerify(compilation1, verify: Verification.Fails, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("System.TypedReference");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name, hasObsolete: false);
AssertReferencedIsByRefLike(type, hasObsolete: false);
type = module.ContainingAssembly.GetTypeByMetadataName("System.ArgIterator");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name, hasObsolete: false);
AssertReferencedIsByRefLike(type, hasObsolete: false);
type = module.ContainingAssembly.GetTypeByMetadataName("System.RuntimeArgumentHandle");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name, hasObsolete: false);
AssertReferencedIsByRefLike(type, hasObsolete: false);
// control case. Not a special type.
type = module.ContainingAssembly.GetTypeByMetadataName("System.NotTypedReference");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name, hasObsolete: true);
AssertReferencedIsByRefLike(type, hasObsolete: true);
});
}
......@@ -990,24 +984,17 @@ namespace System
{
var type = module.ContainingAssembly.GetTypeByMetadataName("System.TypedReference");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
AssertReferencedIsByRefLike(type);
});
}
private static void AssertReferencedIsByRefLikeAttributes(
Accessibility accessibility,
TypeSymbol type,
string assemblyName,
bool hasObsolete = true)
private static void AssertReferencedIsByRefLike(TypeSymbol type, bool hasObsolete = true)
{
var peType = (PENamedTypeSymbol)type;
Assert.True(peType.IsByRefLikeType);
// Single(), as there is no [Obsolete] attribute returned
var isByRefLikeAttribute = peType.GetAttributes().Single().AttributeClass;
Assert.Equal("System.Runtime.CompilerServices.IsByRefLikeAttribute", isByRefLikeAttribute.ToDisplayString());
Assert.Equal(assemblyName, isByRefLikeAttribute.ContainingAssembly.Name);
Assert.Equal(accessibility, isByRefLikeAttribute.DeclaredAccessibility);
// there is no [Obsolete] or [IsByRef] attribute returned
Assert.Empty(peType.GetAttributes());
var peModule = (PEModuleSymbol)peType.ContainingModule;
var obsoleteAttribute = peModule.Module.TryGetDeprecatedOrExperimentalOrObsoleteAttribute(peType.Handle, ignoreByRefLikeMarker: false);
......@@ -1026,7 +1013,7 @@ namespace System
private static void AssertNotReferencedIsByRefLikeAttribute(ImmutableArray<CSharpAttributeData> attributes)
{
foreach(var attr in attributes)
foreach (var attr in attributes)
{
Assert.NotEqual("IsByRefLikeAttribute", attr.AttributeClass.Name);
}
......
......@@ -34,8 +34,11 @@ class Test
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsReadOnly);
Assert.Empty(type.GetAttributes());
AssertReferencedIsReadOnlyAttribute(Accessibility.Public, type.GetAttributes(), module.ContainingAssembly.Name);
var peModule = (PEModuleSymbol)module;
Assert.True(peModule.Module.HasIsReadOnlyAttribute(((PENamedTypeSymbol)type).Handle));
AssertDeclaresType(peModule, WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute, Accessibility.Public);
});
}
......@@ -50,8 +53,7 @@ public void IsReadOnlyIsWrittenToMetadata_NeedsToBeGenerated()
{
var type = module.ContainingAssembly.GetTypeByMetadataName("S1");
Assert.True(type.IsReadOnly);
AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
Assert.Empty(type.GetAttributes());
});
}