/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Symbol/Symbols/Retargeting/RetargetCustomAttributes.cs
398 строк
17 KB
Jared Parsons
Move to basic ref assemblies for net40 (#74796)
19 авг 2024, 18:39
Не верифицирован
19 авг 2024, 18:39
2d074ba
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Linq; using System.Reflection.Metadata; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Roslyn.Test.Utilities; using System.Collections.Generic; using Xunit; using Basic.Reference.Assemblies; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.Retargeting { public class RetargetCustomAttributes : CSharpTestBase { internal class Test01 { public CSharpCompilationReference c1, c2; public AssemblySymbol c1MscorLibAssemblyRef, c2MscorlibAssemblyRef; public NamedTypeSymbol oldMsCorLib_debuggerTypeProxyAttributeType, newMsCorLib_debuggerTypeProxyAttributeType; public MethodSymbol oldMsCorLib_debuggerTypeProxyAttributeCtor, newMsCorLib_debuggerTypeProxyAttributeCtor; public NamedTypeSymbol oldMsCorLib_systemType, newMsCorLib_systemType; private static readonly AttributeDescription s_attribute = new AttributeDescription( "System.Diagnostics", "DebuggerTypeProxyAttribute", new byte[][] { new byte[] { (byte)SignatureAttributes.Instance, 1, (byte)SignatureTypeCode.Void, (byte)SignatureTypeCode.TypeHandle, (byte)AttributeDescription.TypeHandleTarget.SystemType } }); public Test01() { string source = @" using System.Diagnostics; [assembly: DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] [module: DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] [DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] class TestClass { [DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] public int testField; [DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] public int TestProperty { [return: DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] get { return testField; } } [return: DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] [DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] public T TestMethod<[DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] T> ([DebuggerTypeProxyAttribute(typeof(System.Type), Target = typeof(int[]), TargetTypeName = ""IntArrayType"" )] T testParameter) { return testParameter; } }"; var compilation1 = CSharpCompilation.Create("C1", new[] { Parse(source) }, new[] { OldMsCorLib }, TestOptions.ReleaseDll); c1 = new CSharpCompilationReference(compilation1); var c1Assembly = compilation1.Assembly; var compilation2 = CSharpCompilation.Create("C2", references: new MetadataReference[] { NewMsCorLib, c1 }); c2 = new CSharpCompilationReference(compilation2); var c1AsmRef = compilation2.GetReferencedAssemblySymbol(c1); Assert.NotSame(c1Assembly, c1AsmRef); c1MscorLibAssemblyRef = compilation1.GetReferencedAssemblySymbol(OldMsCorLib); c2MscorlibAssemblyRef = compilation2.GetReferencedAssemblySymbol(NewMsCorLib); Assert.NotSame(c1MscorLibAssemblyRef, c2MscorlibAssemblyRef); oldMsCorLib_systemType = c1MscorLibAssemblyRef.GetTypeByMetadataName("System.Type"); newMsCorLib_systemType = c2MscorlibAssemblyRef.GetTypeByMetadataName("System.Type"); Assert.NotSame(oldMsCorLib_systemType, newMsCorLib_systemType); oldMsCorLib_debuggerTypeProxyAttributeType = c1MscorLibAssemblyRef.GetTypeByMetadataName("System.Diagnostics.DebuggerTypeProxyAttribute"); newMsCorLib_debuggerTypeProxyAttributeType = c2MscorlibAssemblyRef.GetTypeByMetadataName("System.Diagnostics.DebuggerTypeProxyAttribute"); Assert.NotSame(oldMsCorLib_debuggerTypeProxyAttributeType, newMsCorLib_debuggerTypeProxyAttributeType); oldMsCorLib_debuggerTypeProxyAttributeCtor = (MethodSymbol)oldMsCorLib_debuggerTypeProxyAttributeType.GetMembers(".ctor").Single( m => ((MethodSymbol)m).ParameterCount == 1 && TypeSymbol.Equals(((MethodSymbol)m).GetParameterType(0), oldMsCorLib_systemType, TypeCompareKind.ConsiderEverything2)); newMsCorLib_debuggerTypeProxyAttributeCtor = (MethodSymbol)newMsCorLib_debuggerTypeProxyAttributeType.GetMembers(".ctor").Single( m => ((MethodSymbol)m).ParameterCount == 1 && TypeSymbol.Equals(((MethodSymbol)m).GetParameterType(0), newMsCorLib_systemType, TypeCompareKind.ConsiderEverything2)); Assert.NotSame(oldMsCorLib_debuggerTypeProxyAttributeCtor, newMsCorLib_debuggerTypeProxyAttributeCtor); } public void TestAttributeRetargeting(Symbol symbol) { // Verify GetAttributes() TestAttributeRetargeting(symbol.GetAttributes()); // Verify GetAttributes(AttributeType from Retargeted assembly) TestAttributeRetargeting(symbol.GetAttributes(newMsCorLib_debuggerTypeProxyAttributeType)); // Verify GetAttributes(AttributeType from Underlying assembly) Assert.Empty(symbol.GetAttributes(oldMsCorLib_debuggerTypeProxyAttributeType)); // Verify GetAttributes(AttributeCtor from Retargeted assembly) TestAttributeRetargeting(symbol.GetAttributes(newMsCorLib_debuggerTypeProxyAttributeType)); // Verify GetAttributes(AttributeCtor from Underlying assembly) Assert.Empty(symbol.GetAttributes(oldMsCorLib_debuggerTypeProxyAttributeType)); // Verify GetAttributes(namespaceName, typeName, ctorSignature) TestAttributeRetargeting(symbol.GetAttributes(s_attribute)); } public void TestAttributeRetargeting_ReturnTypeAttributes(MethodSymbol symbol) { // Verify GetReturnTypeAttributes() TestAttributeRetargeting(symbol.GetReturnTypeAttributes()); // Verify GetReturnTypeAttributes(AttributeType from Retargeted assembly) TestAttributeRetargeting(symbol.GetReturnTypeAttributes().Where(a => TypeSymbol.Equals(a.AttributeClass, newMsCorLib_debuggerTypeProxyAttributeType, TypeCompareKind.ConsiderEverything2))); // Verify GetReturnTypeAttributes(AttributeType from Underlying assembly) returns nothing. Shouldn't match to old attr type Assert.Empty(symbol.GetReturnTypeAttributes().Where(a => TypeSymbol.Equals(a.AttributeClass, oldMsCorLib_debuggerTypeProxyAttributeType, TypeCompareKind.ConsiderEverything2))); // Verify GetReturnTypeAttributes(AttributeCtor from Retargeted assembly) TestAttributeRetargeting(symbol.GetReturnTypeAttributes().Where(a => a.AttributeConstructor == newMsCorLib_debuggerTypeProxyAttributeCtor)); // Verify GetReturnTypeAttributes(AttributeCtor from Underlying assembly) returns nothing. Shouldn't match to old attr type. Assert.Empty(symbol.GetReturnTypeAttributes().Where(a => a.AttributeConstructor == oldMsCorLib_debuggerTypeProxyAttributeCtor)); } private void TestAttributeRetargeting(IEnumerable<CSharpAttributeData> attributes) { Assert.Equal(1, attributes.Count()); var attribute = attributes.First(); Assert.IsType<RetargetingAttributeData>(attribute); Assert.Same(newMsCorLib_debuggerTypeProxyAttributeType, attribute.AttributeClass); Assert.Same(newMsCorLib_debuggerTypeProxyAttributeCtor, attribute.AttributeConstructor); Assert.Same(newMsCorLib_systemType, attribute.AttributeConstructor.GetParameterType(0)); Assert.Equal(1, attribute.CommonConstructorArguments.Length); attribute.VerifyValue(0, TypedConstantKind.Type, newMsCorLib_systemType); Assert.Equal(2, attribute.CommonNamedArguments.Length); attribute.VerifyNamedArgumentValue<object>(0, "Target", TypedConstantKind.Type, typeof(int[])); attribute.VerifyNamedArgumentValue(1, "TargetTypeName", TypedConstantKind.Primitive, "IntArrayType"); } } private static MetadataReference OldMsCorLib { get { return Net40.References.mscorlib; } } private static MetadataReference NewMsCorLib { get { return NetFramework.mscorlib; } } [Fact] public void Test01_AssemblyAttribute() { Test01 test = new Test01(); var c1AsmRef = test.c2.Compilation.GetReferencedAssemblySymbol(test.c1); Assert.IsType<RetargetingAssemblySymbol>(c1AsmRef); test.TestAttributeRetargeting(c1AsmRef); } [Fact] public void Test01_ModuleAttribute() { Test01 test = new Test01(); var c1AsmRef = test.c2.Compilation.GetReferencedAssemblySymbol(test.c1); var c1ModuleSym = c1AsmRef.Modules[0]; Assert.IsType<RetargetingModuleSymbol>(c1ModuleSym); test.TestAttributeRetargeting(c1ModuleSym); } [Fact] public void Test01_NamedTypeAttribute() { Test01 test = new Test01(); var testClass = test.c2.Compilation.GlobalNamespace.GetTypeMembers("TestClass").Single(); Assert.IsType<RetargetingNamedTypeSymbol>(testClass); test.TestAttributeRetargeting(testClass); } [Fact] public void Test01_FieldAttribute() { Test01 test = new Test01(); var testClass = test.c2.Compilation.GlobalNamespace.GetTypeMembers("TestClass").Single(); FieldSymbol testField = testClass.GetMembers("testField").OfType<FieldSymbol>().Single(); Assert.IsType<RetargetingFieldSymbol>(testField); test.TestAttributeRetargeting(testField); } [Fact] public void Test01_PropertyAttribute() { Test01 test = new Test01(); var testClass = test.c2.Compilation.GlobalNamespace.GetTypeMembers("TestClass").Single(); PropertySymbol testProperty = testClass.GetMembers("TestProperty").OfType<PropertySymbol>().Single(); Assert.IsType<RetargetingPropertySymbol>(testProperty); test.TestAttributeRetargeting(testProperty); MethodSymbol testMethod = testProperty.GetMethod; Assert.IsType<RetargetingMethodSymbol>(testMethod); test.TestAttributeRetargeting_ReturnTypeAttributes(testMethod); } [Fact] public void Test01_MethodAttribute() { Test01 test = new Test01(); var testClass = test.c2.Compilation.GlobalNamespace.GetTypeMembers("TestClass").Single(); MethodSymbol testMethod = testClass.GetMembers("TestMethod").OfType<MethodSymbol>().Single(); Assert.IsType<RetargetingMethodSymbol>(testMethod); test.TestAttributeRetargeting(testMethod); } [Fact] public void Test01_TypeParameterAttribute() { Test01 test = new Test01(); var testClass = test.c2.Compilation.GlobalNamespace.GetTypeMembers("TestClass").Single(); MethodSymbol testMethod = testClass.GetMembers("TestMethod").OfType<MethodSymbol>().Single(); Assert.IsType<RetargetingMethodSymbol>(testMethod); TypeParameterSymbol testTypeParameter = testMethod.TypeParameters[0]; Assert.IsType<RetargetingTypeParameterSymbol>(testTypeParameter); test.TestAttributeRetargeting(testTypeParameter); } [Fact] public void Test01_ParameterAttribute() { Test01 test = new Test01(); var testClass = test.c2.Compilation.GlobalNamespace.GetTypeMembers("TestClass").Single(); MethodSymbol testMethod = testClass.GetMembers("TestMethod").OfType<MethodSymbol>().Single(); Assert.IsType<RetargetingMethodSymbol>(testMethod); ParameterSymbol testParameter = testMethod.Parameters[0]; Assert.IsType<RetargetingMethodParameterSymbol>(testParameter); test.TestAttributeRetargeting(testParameter); } [Fact] public void Test01_ReturnTypeAttribute() { Test01 test = new Test01(); var testClass = test.c2.Compilation.GlobalNamespace.GetTypeMembers("TestClass").Single(); MethodSymbol testMethod = testClass.GetMembers("TestMethod").OfType<MethodSymbol>().Single(); Assert.IsType<RetargetingMethodSymbol>(testMethod); test.TestAttributeRetargeting_ReturnTypeAttributes(testMethod); } [Fact] [WorkItem(569089, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/569089"), WorkItem(575948, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/575948")] public void NullArrays() { var source1 = @" using System; public class A : Attribute { public A(object[] a, int[] b) { } public object[] P { get; set; } public int[] F; } [A(null, null, P = null, F = null)] public class C { } "; var source2 = @" "; var c1 = CreateEmptyCompilation(source1, new[] { OldMsCorLib }); var c2 = CreateEmptyCompilation(source2, new MetadataReference[] { NewMsCorLib, new CSharpCompilationReference(c1) }); var c = c2.GlobalNamespace.GetMember<NamedTypeSymbol>("C"); Assert.IsType<RetargetingNamedTypeSymbol>(c); var attr = c.GetAttributes().Single(); var args = attr.ConstructorArguments.ToArray(); Assert.True(args[0].IsNull); Assert.Equal("object[]", args[0].Type.ToDisplayString()); Assert.Throws<InvalidOperationException>(() => args[0].Value); Assert.True(args[1].IsNull); Assert.Equal("int[]", args[1].Type.ToDisplayString()); Assert.Throws<InvalidOperationException>(() => args[1].Value); var named = attr.NamedArguments.ToDictionary(e => e.Key, e => e.Value); Assert.True(named["P"].IsNull); Assert.Equal("object[]", named["P"].Type.ToDisplayString()); Assert.Throws<InvalidOperationException>(() => named["P"].Value); Assert.True(named["F"].IsNull); Assert.Equal("int[]", named["F"].Type.ToDisplayString()); Assert.Throws<InvalidOperationException>(() => named["F"].Value); } [Fact] [WorkItem(65048, "https://github.com/dotnet/roslyn/issues/65048")] public void MissingAttributeType() { var source1 = @" using System; public class A : Attribute { } "; var comp1 = CreateCompilation(source1, options: TestOptions.DebugDll); var source2 = @" [A] public class C1 {} "; var comp2 = CreateCompilation(source2, references: new[] { comp1.ToMetadataReference() }, options: TestOptions.DebugDll); var comp3 = CreateCompilation("", references: new[] { comp2.ToMetadataReference() }, options: TestOptions.DebugDll); var c1 = comp3.GetTypeByMetadataName("C1"); var a = c1.GetAttributes().Single(); Assert.Equal("A[missing]", a.ToString()); Assert.IsAssignableFrom<MissingMetadataTypeSymbol>(a.AttributeClass); Assert.Null(a.AttributeConstructor); } [Fact] [WorkItem(65048, "https://github.com/dotnet/roslyn/issues/65048")] public void MissingAttributeConstructor() { var source1_1 = @" using System; public class A : Attribute { } "; var comp1_1 = CreateCompilation(source1_1, options: TestOptions.DebugDll, assemblyName: "Lib65048"); var source2 = @" [A] public class C1 {} "; var comp2 = CreateCompilation(source2, references: new[] { comp1_1.ToMetadataReference() }, options: TestOptions.DebugDll); var source1_2 = @" using System; public class A : Attribute { public A(int x) {} } "; var comp1_2 = CreateCompilation(source1_2, options: TestOptions.DebugDll, assemblyName: "Lib65048"); var comp3 = CreateCompilation("", references: new[] { comp2.ToMetadataReference(), comp1_2.ToMetadataReference() }, options: TestOptions.DebugDll); var c1 = comp3.GetTypeByMetadataName("C1"); var a = c1.GetAttributes().Single(); Assert.Equal("A", a.ToString()); Assert.False(a.AttributeClass.IsErrorType()); Assert.Null(a.AttributeConstructor); } } }