未验证 提交 e0ddfbc8 编写于 作者: J Julien Couvreur 提交者: GitHub

Override completion with in parameter should omit IsReadOnly attribute (#24492)

上级 f9e57da1
......@@ -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());
});
}
......@@ -69,8 +71,7 @@ class Test
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsReadOnly);
AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
Assert.Empty(type.GetAttributes());
});
}
......@@ -88,8 +89,7 @@ class Test
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test+S1`1");
Assert.True(type.IsReadOnly);
AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
Assert.Empty(type.GetAttributes());
});
}
......@@ -107,8 +107,7 @@ class Test<T>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test`1").GetTypeMember("S1");
Assert.True(type.IsReadOnly);
AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
Assert.Empty(type.GetAttributes());
});
}
......@@ -134,8 +133,7 @@ class Test
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsReadOnly);
AssertReferencedIsReadOnlyAttribute(Accessibility.Public, type.GetAttributes(), referenceA.Compilation.AssemblyName);
Assert.Empty(type.GetAttributes());
AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly);
});
}
......@@ -429,8 +427,7 @@ public class Test
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsReadOnly);
AssertReferencedIsReadOnlyAttribute(Accessibility.Public, type.GetAttributes(), reference.Display);
Assert.Empty(type.GetAttributes());
AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly);
});
}
......@@ -580,7 +577,7 @@ public interface Test
var property = type.GetMember<PEPropertySymbol>("Property");
Assert.NotNull(property);
AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, property.Type.GetAttributes(), module.ContainingAssembly.Name);
AssertNotReferencedIsReadOnlyAttribute(type.GetAttributes());
});
var code = @"
......@@ -637,17 +634,9 @@ public class Test
);
}
private static void AssertReferencedIsReadOnlyAttribute(Accessibility accessibility, ImmutableArray<CSharpAttributeData> attributes, string assemblyName)
{
var attributeType = attributes.Single().AttributeClass;
Assert.Equal("System.Runtime.CompilerServices.IsReadOnlyAttribute", attributeType.ToDisplayString());
Assert.Equal(assemblyName, attributeType.ContainingAssembly.Name);
Assert.Equal(accessibility, attributeType.DeclaredAccessibility);
}
private static void AssertNotReferencedIsReadOnlyAttribute(ImmutableArray<CSharpAttributeData> attributes)
{
foreach(var attr in attributes)
foreach (var attr in attributes)
{
Assert.NotEqual("IsReadOnlyAttribute", attr.AttributeClass.Name);
}
......
......@@ -5,6 +5,7 @@
using System.Collections.Immutable;
using System.Linq;
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.Test.Utilities;
......@@ -114,7 +115,7 @@ static void Main()
}
";
var comp = CompileAndVerify(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef, ref1}, parseOptions: TestOptions.Regular, verify: Verification.Fails, expectedOutput: @"12");
var comp = CompileAndVerify(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef, ref1 }, parseOptions: TestOptions.Regular, verify: Verification.Fails, expectedOutput: @"12");
comp.VerifyIL("Program.Main", @"
{
......@@ -817,6 +818,16 @@ public override string ToString()
Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind);
Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind);
void validate(ModuleSymbol module)
{
var test = module.ContainingAssembly.GetTypeByMetadataName("Program+S1");
var peModule = (PEModuleSymbol)module;
Assert.True(peModule.Module.HasIsReadOnlyAttribute(((PENamedTypeSymbol)test).Handle));
AssertDeclaresType(peModule, WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute, Accessibility.Internal);
}
CompileAndVerify(comp, symbolValidator: validate);
// S1<T>
namedType = comp.GetTypeByMetadataName("Program+S1`1");
Assert.True(namedType.IsReadOnly);
......@@ -882,6 +893,14 @@ public override string ToString()
type = (TypeSymbol)comp.CreateTupleTypeSymbol(ImmutableArray.Create<ITypeSymbol>(comp.ObjectType, comp.ObjectType));
Assert.False(type.IsReadOnly);
// S1 from image
var clientComp = CreateStandardCompilation("", references: new[] { comp.EmitToImageReference() });
NamedTypeSymbol s1 = clientComp.GetTypeByMetadataName("Program+S1");
Assert.True(s1.IsReadOnly);
Assert.Empty(s1.GetAttributes());
Assert.Equal(RefKind.Out, s1.Constructors[0].ThisParameter.RefKind);
Assert.Equal(RefKind.In, s1.GetMethod("M1").ThisParameter.RefKind);
Assert.Equal(RefKind.In, s1.GetMethod("ToString").ThisParameter.RefKind);
}
[Fact]
......
......@@ -532,10 +532,10 @@ public void RefAssembly_HasReferenceAssemblyAttribute()
var reader = assembly.GetMetadataReader();
var attributes = reader.GetAssemblyDefinition().GetCustomAttributes();
AssertEx.Equal(new[] {
"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute.ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute.ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute.ctor(DebuggingModes)",
"MemberReference:Void System.Runtime.CompilerServices.ReferenceAssemblyAttribute.ctor()"
"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute..ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute..ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute..ctor(DebuggingModes)",
"MemberReference:Void System.Runtime.CompilerServices.ReferenceAssemblyAttribute..ctor()"
},
attributes.Select(a => MetadataReaderUtils.Dump(reader, reader.GetCustomAttribute(a).Constructor)));
};
......@@ -554,9 +554,9 @@ public void RefAssembly_HandlesMissingReferenceAssemblyAttribute()
var attributes = reader.GetAssemblyDefinition().GetCustomAttributes();
AssertEx.SetEqual(attributes.Select(a => MetadataReaderUtils.Dump(reader, reader.GetCustomAttribute(a).Constructor)),
new string[] {
"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute.ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute.ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute.ctor(DebuggingModes)"
"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute..ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute..ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute..ctor(DebuggingModes)"
});
};
......@@ -575,10 +575,10 @@ public void RefAssembly_ReferenceAssemblyAttributeAlsoInSource()
var reader = assembly.GetMetadataReader();
var attributes = reader.GetAssemblyDefinition().GetCustomAttributes();
AssertEx.Equal(new string[] {
"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute.ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute.ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute.ctor(DebuggingModes)",
"MemberReference:Void System.Runtime.CompilerServices.ReferenceAssemblyAttribute.ctor()"
"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute..ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute..ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute..ctor(DebuggingModes)",
"MemberReference:Void System.Runtime.CompilerServices.ReferenceAssemblyAttribute..ctor()"
},
attributes.Select(a => MetadataReaderUtils.Dump(reader, reader.GetCustomAttribute(a).Constructor)));
};
......
......@@ -35,8 +35,17 @@ public static void Main()
}
}";
CompileAndVerify(code, additionalRefs: new[] { reference.ToMetadataReference() }, expectedOutput: "5");
CompileAndVerify(code, additionalRefs: new[] { reference.EmitToImageReference() }, expectedOutput: "5");
var verifier = CompileAndVerify(code, additionalRefs: new[] { reference.ToMetadataReference() }, expectedOutput: "5");
verifyParameter(verifier.Compilation);
verifier = CompileAndVerify(code, additionalRefs: new[] { reference.EmitToImageReference() }, expectedOutput: "5");
verifyParameter(verifier.Compilation);
void verifyParameter(Compilation comp)
{
var m = (IMethodSymbol)comp.GetMember("TestRef.M");
Assert.Empty(m.Parameters[0].GetAttributes());
}
}
[Fact]
......
......@@ -8499,7 +8499,7 @@ End Class")
MetadataReaderUtils.VerifyPEMetadata(exe,
{"TypeDefinition:<Module>", "TypeDefinition:C"},
{"MethodDefinition:Void Main()", "MethodDefinition:Void .ctor()", "MethodDefinition:Void PrivateMethod()"},
{"MethodDefinition:Void C.Main()", "MethodDefinition:Void C..ctor()", "MethodDefinition:Void C.PrivateMethod()"},
{"CompilationRelaxationsAttribute", "RuntimeCompatibilityAttribute", "DebuggableAttribute", "STAThreadAttribute"}
)
......@@ -8536,7 +8536,7 @@ a
' See issue https://github.com/dotnet/roslyn/issues/17612
MetadataReaderUtils.VerifyPEMetadata(refDll,
{"TypeDefinition:<Module>", "TypeDefinition:C"},
{"MethodDefinition:Void Main()", "MethodDefinition:Void .ctor()"},
{"MethodDefinition:Void C.Main()", "MethodDefinition:Void C..ctor()"},
{"CompilationRelaxationsAttribute", "RuntimeCompatibilityAttribute", "DebuggableAttribute", "STAThreadAttribute", "ReferenceAssemblyAttribute"}
)
......@@ -8619,7 +8619,7 @@ End Class")
' See issue https://github.com/dotnet/roslyn/issues/17612
MetadataReaderUtils.VerifyPEMetadata(refDll,
{"TypeDefinition:<Module>", "TypeDefinition:C", "TypeDefinition:S"},
{"MethodDefinition:Void Main()", "MethodDefinition:Void .ctor()"},
{"MethodDefinition:Void C.Main()", "MethodDefinition:Void C..ctor()"},
{"CompilationRelaxationsAttribute", "RuntimeCompatibilityAttribute", "DebuggableAttribute", "STAThreadAttribute", "ReferenceAssemblyAttribute"}
)
......
......@@ -373,10 +373,10 @@ End Class"
Dim reader = assembly.GetMetadataReader()
Dim attributes = reader.GetAssemblyDefinition().GetCustomAttributes()
AssertEx.Equal(
{"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute.ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute.ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute.ctor(DebuggingModes)",
"MemberReference:Void System.Runtime.CompilerServices.ReferenceAssemblyAttribute.ctor()"
{"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute..ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute..ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute..ctor(DebuggingModes)",
"MemberReference:Void System.Runtime.CompilerServices.ReferenceAssemblyAttribute..ctor()"
},
attributes.Select(Function(a) MetadataReaderUtils.Dump(reader, reader.GetCustomAttribute(a).Constructor)))
End Sub
......@@ -412,10 +412,10 @@ End Class"
Dim reader = assembly.GetMetadataReader()
Dim attributes = reader.GetAssemblyDefinition().GetCustomAttributes()
AssertEx.Equal(
{"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute.ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute.ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute.ctor(DebuggingModes)",
"MemberReference:Void System.Runtime.CompilerServices.ReferenceAssemblyAttribute.ctor()"
{"MemberReference:Void System.Runtime.CompilerServices.CompilationRelaxationsAttribute..ctor(Int32)",
"MemberReference:Void System.Runtime.CompilerServices.RuntimeCompatibilityAttribute..ctor()",
"MemberReference:Void System.Diagnostics.DebuggableAttribute..ctor(DebuggingModes)",
"MemberReference:Void System.Runtime.CompilerServices.ReferenceAssemblyAttribute..ctor()"
},
attributes.Select(Function(a) MetadataReaderUtils.Dump(reader, reader.GetCustomAttribute(a).Constructor)))
End Sub
......
......@@ -9,6 +9,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Completion.Providers;
using Microsoft.CodeAnalysis.Editor.UnitTests.Completion;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
......@@ -2693,5 +2694,69 @@ public class Class1
Assert.False(completionList.Items.Any(c => c.DisplayText == "Goo()"));
}
}
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task TestInParameter()
{
var source = XElement.Parse(@"<Workspace>
<Project Name=""P1"" Language=""C#"" LanguageVersion=""Latest"" CommonReferences=""true"" AssemblyName=""Proj1"">
<Document FilePath=""CurrentDocument.cs""><![CDATA[
public class SomeClass : Base
{
override $$
}
]]>
</Document>
</Project>
</Workspace>");
using (var workspace = TestWorkspace.Create(source))
{
var before = @"
public abstract class Base
{
public abstract void M(in int x);
}";
var after = @"
public class SomeClass : Base
{
public override void M(in int x)
{
throw new System.NotImplementedException();
}
}
";
var origComp = await workspace.CurrentSolution.Projects.Single().GetCompilationAsync();
var options = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest);
var libComp = origComp.RemoveAllSyntaxTrees().AddSyntaxTrees(CSharpSyntaxTree.ParseText(before, options: options));
var libRef = MetadataReference.CreateFromImage(Test.Utilities.CompilationExtensions.EmitToArray(libComp));
var project = workspace.CurrentSolution.Projects.Single();
var updatedProject = project.AddMetadataReference(libRef);
workspace.ChangeSolution(updatedProject.Solution);
var provider = new OverrideCompletionProvider();
var testDocument = workspace.Documents.First(d => d.Name == "CurrentDocument.cs");
var document = workspace.CurrentSolution.GetDocument(testDocument.Id);
var service = GetCompletionService(workspace);
var completionList = await GetCompletionListAsync(service, document, testDocument.CursorPosition.Value, CompletionTrigger.Invoke);
var completionItem = completionList.Items.Where(c => c.DisplayText == "M(in int x)").Single();
var commit = await service.GetChangeAsync(document, completionItem, commitKey: null, CancellationToken.None);
var text = await document.GetTextAsync();
var newText = text.WithChanges(commit.TextChange);
var newDoc = document.WithText(newText);
document.Project.Solution.Workspace.TryApplyChanges(newDoc.Project.Solution);
var textBuffer = workspace.Documents.Single().TextBuffer;
string actualCodeAfterCommit = textBuffer.CurrentSnapshot.AsText().ToString();
Assert.Equal(after, actualCodeAfterCommit);
}
}
}
}
......@@ -269,12 +269,6 @@ protected virtual bool CompareItems(string actualItem, string expectedItem)
bool usePreviousCharAsTrigger, bool checkForAbsence,
int? glyph, int? matchPriority, bool? hasSuggestionModeItem)
{
Glyph? expectedGlyph = null;
if (glyph.HasValue)
{
expectedGlyph = (Glyph)glyph.Value;
}
var document1 = WorkspaceFixture.UpdateDocument(code, sourceCodeKind);
await CheckResultsAsync(
document1, position, expectedItemOrNull,
......
......@@ -14,6 +14,7 @@
using System.Threading;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Operations;
using Roslyn.Test.Utilities;
......@@ -501,6 +502,12 @@ internal static Cci.ModulePropertiesForSerialization GetDefaultModulePropertiesF
linkerMinorVersion: 0);
}
internal void AssertDeclaresType(PEModuleSymbol peModule, WellKnownType type, Accessibility expectedAccessibility)
{
var name = MetadataTypeName.FromFullName(type.GetMetadataName());
Assert.Equal(expectedAccessibility, peModule.LookupTopLevelMetadataType(ref name).DeclaredAccessibility);
}
#endregion
#region Metadata Validation
......
......@@ -309,7 +309,7 @@ private static string DumpRec(this MetadataReader reader, EntityHandle handle)
var decoder = new SignatureDecoder<string, object>(ConstantSignatureVisualizer.Instance, reader, genericContext: null);
var signature = decoder.DecodeMethodSignature(ref blob);
var parameters = signature.ParameterTypes.Join(", ");
return $"{signature.ReturnType} {reader.GetString(method.Name)}({parameters})";
return $"{signature.ReturnType} {DumpRec(reader, method.GetDeclaringType())}.{reader.GetString(method.Name)}({parameters})";
}
case HandleKind.MemberReference:
{
......@@ -318,7 +318,7 @@ private static string DumpRec(this MetadataReader reader, EntityHandle handle)
var decoder = new SignatureDecoder<string, object>(ConstantSignatureVisualizer.Instance, reader, genericContext: null);
var signature = decoder.DecodeMethodSignature(ref blob);
var parameters = signature.ParameterTypes.Join(", ");
return $"{signature.ReturnType} {DumpRec(reader, member.Parent)}{reader.GetString(member.Name)}({parameters})";
return $"{signature.ReturnType} {DumpRec(reader, member.Parent)}.{reader.GetString(member.Name)}({parameters})";
}
case HandleKind.TypeReference:
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册