1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Linq;
6 using Internal.Metadata.NativeFormat.Writer;
7 using ILCompiler.Metadata;
8 
9 using Cts = Internal.TypeSystem;
10 using NativeFormat = Internal.Metadata.NativeFormat;
11 
12 using Xunit;
13 
14 namespace MetadataTransformTests
15 {
16     public class ExplicitScopeTests
17     {
18         private TestTypeSystemContext _context;
19         private Cts.Ecma.EcmaModule _systemModule;
20 
ExplicitScopeTests()21         public ExplicitScopeTests()
22         {
23             _context = new TestTypeSystemContext();
24             _systemModule = _context.CreateModuleForSimpleName("PrimaryMetadataAssembly");
25             _context.SetSystemModule(_systemModule);
26         }
27 
GetScopeDefinitionOfType(TypeDefinition typeDefinition)28         public ScopeDefinition GetScopeDefinitionOfType(TypeDefinition typeDefinition)
29         {
30             Assert.NotNull(typeDefinition);
31             ScopeDefinition scope = null;
32             NamespaceDefinition currentNamespaceDefinition = typeDefinition.NamespaceDefinition;
33 
34             while (scope == null)
35             {
36                 Assert.NotNull(currentNamespaceDefinition);
37                 scope = currentNamespaceDefinition.ParentScopeOrNamespace as ScopeDefinition;
38                 currentNamespaceDefinition = currentNamespaceDefinition.ParentScopeOrNamespace as NamespaceDefinition;
39             }
40 
41             return scope;
42         }
43 
GetScopeReferenceOfType(TypeReference typeReference)44         public ScopeReference GetScopeReferenceOfType(TypeReference typeReference)
45         {
46             Assert.NotNull(typeReference);
47             ScopeReference scope = null;
48             NamespaceReference currentNamespaceReference = typeReference.ParentNamespaceOrType as NamespaceReference;
49 
50             while (scope == null)
51             {
52                 Assert.NotNull(currentNamespaceReference);
53                 scope = currentNamespaceReference.ParentScopeOrNamespace as ScopeReference;
54                 currentNamespaceReference = currentNamespaceReference.ParentScopeOrNamespace as NamespaceReference;
55             }
56 
57             return scope;
58         }
59 
CheckTypeDefinitionForProperWinRTHome(TypeDefinition typeDefinition, string module)60         public void CheckTypeDefinitionForProperWinRTHome(TypeDefinition typeDefinition, string module)
61         {
62             ScopeDefinition scope = GetScopeDefinitionOfType(typeDefinition);
63             Assert.Equal(module, scope.Name.Value);
64             int windowsRuntimeFlag = ((int)System.Reflection.AssemblyContentType.WindowsRuntime << 9);
65             Assert.True((((int)scope.Flags) & windowsRuntimeFlag) == windowsRuntimeFlag);
66         }
67 
68 
CheckTypeReferenceForProperWinRTHome(TypeReference typeReference, string module)69         public void CheckTypeReferenceForProperWinRTHome(TypeReference typeReference, string module)
70         {
71             ScopeReference scope = GetScopeReferenceOfType(typeReference);
72             Assert.Equal(module, scope.Name.Value);
73             int windowsRuntimeFlag = ((int)System.Reflection.AssemblyContentType.WindowsRuntime << 9);
74             Assert.True((((int)scope.Flags) & windowsRuntimeFlag) == windowsRuntimeFlag);
75         }
76 
77         [Fact]
TestExplicitScopeAttributesForWinRTSingleFilePolicy()78         public void TestExplicitScopeAttributesForWinRTSingleFilePolicy()
79         {
80             // Test that custom attributes referring to blocked types don't show up in metadata
81 
82             var sampleMetadataModule = _context.GetModuleForSimpleName("SampleMetadataAssembly");
83             var sampleWinRTMetadataModule = _context.GetModuleForSimpleName("SampleWinRTMetadataAssembly");
84             var windowsWinRTMetadataModule = _context.GetModuleForSimpleName("WindowsWinRTMetadataAssembly");
85 
86             Cts.MetadataType controlType = windowsWinRTMetadataModule.GetType("Windows", "Control");
87             Cts.MetadataType derivedFromControl = sampleWinRTMetadataModule.GetType("SampleMetadataWinRT", "DerivedFromControl");
88             Cts.MetadataType derivedFromControlInCustomScope = sampleWinRTMetadataModule.GetType("SampleMetadataWinRT", "DerivedFromControlAndInCustomScope");
89 
90             var policy = new SingleFileMetadataPolicy();
91 
92             var transformResult = MetadataTransform.Run(policy,
93                 new[] { _systemModule, sampleMetadataModule, sampleWinRTMetadataModule, windowsWinRTMetadataModule });
94 
95             var controlTypeMetadata = transformResult.GetTransformedTypeDefinition(controlType);
96             var derivedFromControlMetadata = transformResult.GetTransformedTypeDefinition(derivedFromControl);
97             var derivedFromControlInCustomScopeMetadata = transformResult.GetTransformedTypeDefinition(derivedFromControlInCustomScope);
98 
99             CheckTypeDefinitionForProperWinRTHome(controlTypeMetadata, "Windows");
100             ScopeDefinition scopeDefOfDerivedFromControlType = GetScopeDefinitionOfType(derivedFromControlMetadata);
101             Assert.Equal("SampleWinRTMetadataAssembly", scopeDefOfDerivedFromControlType.Name.Value);
102             CheckTypeDefinitionForProperWinRTHome(derivedFromControlInCustomScopeMetadata, "SampleMetadataWinRT");
103         }
104 
105 
106         [Fact]
TestExplicitScopeAttributesForWinRTMultiFilePolicy()107         public void TestExplicitScopeAttributesForWinRTMultiFilePolicy()
108         {
109             // Test that custom attributes referring to blocked types don't show up in metadata
110 
111             var sampleMetadataModule = _context.GetModuleForSimpleName("SampleMetadataAssembly");
112             var sampleWinRTMetadataModule = _context.GetModuleForSimpleName("SampleWinRTMetadataAssembly");
113             var windowsWinRTMetadataModule = _context.GetModuleForSimpleName("WindowsWinRTMetadataAssembly");
114 
115             Cts.MetadataType controlType = windowsWinRTMetadataModule.GetType("Windows", "Control");
116             Cts.MetadataType derivedFromControl = sampleWinRTMetadataModule.GetType("SampleMetadataWinRT", "DerivedFromControl");
117             Cts.MetadataType derivedFromControlInCustomScope = sampleWinRTMetadataModule.GetType("SampleMetadataWinRT", "DerivedFromControlAndInCustomScope");
118 
119             var policy = new MultifileMetadataPolicy(sampleMetadataModule, sampleWinRTMetadataModule);
120 
121             var transformResult = MetadataTransform.Run(policy,
122                 new[] { _systemModule, sampleMetadataModule, sampleWinRTMetadataModule, windowsWinRTMetadataModule });
123 
124             var controlTypeMetadata = transformResult.GetTransformedTypeReference(controlType);
125             var derivedFromControlMetadata = transformResult.GetTransformedTypeDefinition(derivedFromControl);
126             var derivedFromControlInCustomScopeMetadata = transformResult.GetTransformedTypeDefinition(derivedFromControlInCustomScope);
127 
128             CheckTypeReferenceForProperWinRTHome(controlTypeMetadata, "Windows");
129             ScopeDefinition scopeDefOfDerivedFromControlType = GetScopeDefinitionOfType(derivedFromControlMetadata);
130             Assert.Equal("SampleWinRTMetadataAssembly", scopeDefOfDerivedFromControlType.Name.Value);
131             CheckTypeDefinitionForProperWinRTHome(derivedFromControlInCustomScopeMetadata, "SampleMetadataWinRT");
132         }
133     }
134 }
135