提交 0f6b30e5 编写于 作者: O Omar Tawfik 提交者: GitHub

Compiler API not to return [Obsolete] for IsByRefLikeTypes (#22553)

* Compiler API not to return [Obsolete] for IsByRefLikeTypes

* Clean up

* typo
上级 bcd928be
......@@ -600,17 +600,16 @@ public override ImmutableArray<CSharpAttributeData> GetAttributes()
if (uncommon.lazyCustomAttributes.IsDefault)
{
if (MightContainExtensionMethods)
{
this.ContainingPEModule.LoadCustomAttributesFilterExtensions(
this.Handle,
ref uncommon.lazyCustomAttributes);
}
else
{
this.ContainingPEModule.LoadCustomAttributes(this.Handle,
ref uncommon.lazyCustomAttributes);
}
var loadedCustomAttributes = ContainingPEModule.GetCustomAttributesForToken(
Handle,
out _,
// Filter out [Extension]
MightContainExtensionMethods ? AttributeDescription.CaseSensitiveExtensionAttribute : default,
out _,
// Filter out [Obsolete], unless it was user defined
(IsByRefLikeType && ObsoleteAttributeData is null) ? AttributeDescription.ObsoleteAttribute : default);
ImmutableInterlocked.InterlockedInitialize(ref uncommon.lazyCustomAttributes, loadedCustomAttributes);
}
return uncommon.lazyCustomAttributes;
......
......@@ -32,9 +32,7 @@ class Test
CompileAndVerify(text, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type.GetAttributes(), module.ContainingAssembly.Name);
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type, module.ContainingAssembly.Name);
});
}
......@@ -48,9 +46,7 @@ public void IsByRefLikeIsWrittenToMetadata_NeedsToBeGenerated()
CompileAndVerify(text, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("S1");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
});
}
......@@ -67,9 +63,7 @@ class Test
CompileAndVerify(text, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
});
}
......@@ -86,9 +80,7 @@ class Test
CompileAndVerify(text, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test+S1`1");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
});
}
......@@ -105,9 +97,7 @@ class Test<T>
CompileAndVerify(text, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test`1").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
});
}
......@@ -132,9 +122,8 @@ class Test
CompileAndVerify(codeB, verify: false, additionalRefs: new[] { referenceA }, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type.GetAttributes(), referenceA.Compilation.AssemblyName);
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type, referenceA.Compilation.AssemblyName);
AssertNoIsByRefLikeAttributeExists(module.ContainingAssembly);
});
}
......@@ -427,9 +416,8 @@ public class Test
CompileAndVerify(code, verify: false, additionalRefs: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type.GetAttributes(), reference.Display);
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type, reference.Display);
AssertNoIsByRefLikeAttributeExists(module.ContainingAssembly);
});
}
......@@ -579,7 +567,7 @@ public interface Test
var property = type.GetMember<PEPropertySymbol>("Property");
Assert.NotNull(property);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, property.Type.GetAttributes(), module.ContainingAssembly.Name);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, property.Type, module.ContainingAssembly.Name);
});
var code = @"
......@@ -698,18 +686,7 @@ public class ObsoleteAttribute{}
CompileAndVerify(text, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
var accessibility = Accessibility.Public;
var attributes = type.GetAttributes();
Assert.Equal(1, 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);
AssertReferencedIsByRefLikeAttributes(Accessibility.Public, type, module.ContainingAssembly.Name, hasObsolete: false);
});
}
......@@ -878,25 +855,7 @@ public void ObsoleteHasErrorEqualsTrue()
CompileAndVerify(text, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("S");
Assert.True(type.IsByRefLikeType);
var attributes = type.GetAttributes();
Assert.Equal(2, attributes.Length);
var attributeType = attributes[0].AttributeClass;
Assert.Equal("System.Runtime.CompilerServices.IsByRefLikeAttribute", attributeType.ToDisplayString());
var assemblyName = module.ContainingAssembly.Name;
Assert.Equal(assemblyName, attributeType.ContainingAssembly.Name);
var accessibility = Accessibility.Internal;
Assert.Equal(accessibility, attributeType.DeclaredAccessibility);
var attribute = attributes[1];
Assert.Equal("System.ObsoleteAttribute", attribute.AttributeClass.ToDisplayString());
TypedConstant[] constructorArguments = attribute.ConstructorArguments.ToArray();
Assert.Equal(2, constructorArguments.Length);
Assert.Equal("Types with embedded references are not supported in this version of your compiler.", constructorArguments[0].Value);
Assert.Equal(true, constructorArguments[1].Value);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
});
}
......@@ -1003,25 +962,17 @@ public class ObsoleteAttribute: Attribute
CompileAndVerify(compilation1, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("System.TypedReference");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name, hasObsolete: false);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name, hasObsolete: false);
type = module.ContainingAssembly.GetTypeByMetadataName("System.ArgIterator");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name, hasObsolete: false);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name, hasObsolete: false);
type = module.ContainingAssembly.GetTypeByMetadataName("System.RuntimeArgumentHandle");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name, hasObsolete: false);
type = module.ContainingAssembly.GetTypeByMetadataName("System.NotTypedReference");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name, hasObsolete: false);
// control case. Not a special type.
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name, hasObsolete: true);
type = module.ContainingAssembly.GetTypeByMetadataName("System.NotTypedReference");
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name, hasObsolete: true);
});
}
......@@ -1038,31 +989,38 @@ namespace System
CompileAndVerify(text, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("System.TypedReference");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type, module.ContainingAssembly.Name);
});
}
private static void AssertReferencedIsByRefLikeAttributes(
Accessibility accessibility,
ImmutableArray<CSharpAttributeData> attributes,
string assemblyName,
TypeSymbol type,
string assemblyName,
bool hasObsolete = true)
{
Assert.Equal(hasObsolete? 2: 1, attributes.Count());
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);
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 peModule = (PEModuleSymbol)peType.ContainingModule;
var obsoleteAttribute = peModule.Module.TryGetDeprecatedOrExperimentalOrObsoleteAttribute(peType.Handle, ignoreByRefLikeMarker: false);
if (hasObsolete)
{
var attribute = attributes[1];
Assert.Equal("System.ObsoleteAttribute", attribute.AttributeClass.ToDisplayString());
Assert.Equal("Types with embedded references are not supported in this version of your compiler.", attribute.ConstructorArguments.ElementAt(0).Value);
Assert.Equal(true, attribute.ConstructorArguments.ElementAt(1).Value); // error=true
Assert.NotNull(obsoleteAttribute);
Assert.Equal("Types with embedded references are not supported in this version of your compiler.", obsoleteAttribute.Message);
Assert.Equal(true, obsoleteAttribute.IsError);
}
else
{
Assert.Null(obsoleteAttribute);
}
}
......
......@@ -5033,5 +5033,32 @@ class Test
",
MainDescription("Test.Test()"));
}
[WorkItem(22450, "https://github.com/dotnet/roslyn/issues/22450")]
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestRefLikeTypesNoDeprecated()
{
var xmlString = @"
<Workspace>
<Project Language=""C#"" LanguageVersion=""702"" CommonReferences=""true"">
<MetadataReferenceFromSource Language=""C#"" LanguageVersion=""702"" CommonReferences=""true"">
<Document FilePath=""ReferencedDocument"">
public ref struct TestRef
{
}
</Document>
</MetadataReferenceFromSource>
<Document FilePath=""SourceDocument"">
ref struct Test
{
private $$TestRef _field;
}
</Document>
</Project>
</Workspace>";
// There should be no [deprecated] attribute displayed.
await VerifyWithReferenceWorkerAsync(xmlString, MainDescription($"struct TestRef"));
}
}
}
......@@ -736,9 +736,11 @@ private static Compilation CreateCompilation(TestWorkspace workspace, XElement r
var compilation = compilationFactory.CreateCompilation(assemblyName, options);
var documentElements = referencedSource.Elements(DocumentElementName).ToList();
var parseOptions = GetParseOptions(referencedSource, languageName, languageServices);
foreach (var documentElement in documentElements)
{
compilation = compilation.AddSyntaxTrees(CreateSyntaxTree(languageName, documentElement.Value));
compilation = compilation.AddSyntaxTrees(CreateSyntaxTree(parseOptions, documentElement.Value));
}
foreach (var reference in CreateReferenceList(workspace, referencedSource))
......@@ -749,15 +751,15 @@ private static Compilation CreateCompilation(TestWorkspace workspace, XElement r
return compilation;
}
private static SyntaxTree CreateSyntaxTree(string languageName, string referencedCode)
private static SyntaxTree CreateSyntaxTree(ParseOptions options, string referencedCode)
{
if (LanguageNames.CSharp == languageName)
if (LanguageNames.CSharp == options.Language)
{
return Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(referencedCode);
return Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(referencedCode, options);
}
else
{
return Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.ParseSyntaxTree(referencedCode);
return Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.ParseSyntaxTree(referencedCode, options);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册