From 7c809f6c2214c7685fdf6ce7b35b3b4da474b9d7 Mon Sep 17 00:00:00 2001
From: Nate McMaster <natemcmaster@users.noreply.github.com>
Date: Fri, 28 Jun 2019 19:08:01 -0400
Subject: [PATCH] Set ReferenceAssemblyAttribute in reference assemblies
 (#11207)

* Set ReferenceAssemblyAttribute in reference assemblies

* Update ReferenceAssemblyInfo.cs

* Use src project for MVC analyzer tests
---
 Directory.Build.targets                       |  4 +++
 src/Framework/test/TargetingPackTests.cs      | 34 +++++++++++++++++++
 .../test/Mvc.Analyzers.Test.csproj            |  2 +-
 .../test/Mvc.Api.Analyzers.Test.csproj        |  2 +-
 src/Shared/ReferenceAssemblyInfo.cs           | 10 ++++++
 5 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 src/Shared/ReferenceAssemblyInfo.cs

diff --git a/Directory.Build.targets b/Directory.Build.targets
index 3909b2ee759..9f6393d1324 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -98,6 +98,10 @@
     <BuildHelixPayload Condition="'$(BuildHelixPayload)' == '' AND '$(IsTestProject)' == 'true'">true</BuildHelixPayload>
   </PropertyGroup>
 
+  <ItemGroup Condition="'$(Language)' == 'C#' AND '$(IsReferenceAssemblyProject)' == 'true'">
+    <Compile Include="$(SharedSourceRoot)ReferenceAssemblyInfo.cs" LinkBase="Properties" />
+  </ItemGroup>
+
   <ItemGroup>
     <KnownFrameworkReference Update="Microsoft.NETCore.App">
       <!-- Always update the 'latest version', whether the repo is servicing or not. -->
diff --git a/src/Framework/test/TargetingPackTests.cs b/src/Framework/test/TargetingPackTests.cs
index d1c7baf8934..3d3fedc85a7 100644
--- a/src/Framework/test/TargetingPackTests.cs
+++ b/src/Framework/test/TargetingPackTests.cs
@@ -5,6 +5,10 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Reflection;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+using System.Runtime.CompilerServices;
 using Newtonsoft.Json.Linq;
 using Xunit;
 using Xunit.Abstractions;
@@ -24,6 +28,36 @@ namespace Microsoft.AspNetCore
             _targetingPackRoot = Path.Combine(TestData.GetTestDataValue("TargetingPackLayoutRoot"), "packs", "Microsoft.AspNetCore.App.Ref", TestData.GetTestDataValue("TargetingPackVersion"));
         }
 
+        [Fact]
+        public void AssembliesAreReferenceAssemblies()
+        {
+            IEnumerable<string> dlls = Directory.GetFiles(_targetingPackRoot, "*.dll", SearchOption.AllDirectories);
+            Assert.NotEmpty(dlls);
+
+            // Workaround https://github.com/aspnet/AspNetCore/issues/11206
+            dlls = dlls.Where(d => !d.Contains("System.IO.Pipelines"));
+
+            Assert.All(dlls, path =>
+            {
+                var assemblyName = AssemblyName.GetAssemblyName(path);
+                using var fileStream = File.OpenRead(path);
+                using var peReader = new PEReader(fileStream, PEStreamOptions.Default);
+                var reader = peReader.GetMetadataReader(MetadataReaderOptions.Default);
+                var assemblyDefinition = reader.GetAssemblyDefinition();
+                var hasRefAssemblyAttribute = assemblyDefinition.GetCustomAttributes().Any(attr =>
+                {
+                    var attribute = reader.GetCustomAttribute(attr);
+                    var attributeConstructor = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
+                    var attributeType = reader.GetTypeReference((TypeReferenceHandle)attributeConstructor.Parent);
+                    return reader.StringComparer.Equals(attributeType.Namespace, typeof(ReferenceAssemblyAttribute).Namespace)
+                        && reader.StringComparer.Equals(attributeType.Name, nameof(ReferenceAssemblyAttribute));
+                });
+
+                Assert.True(hasRefAssemblyAttribute, $"{path} should have {nameof(ReferenceAssemblyAttribute)}");
+                Assert.Equal(ProcessorArchitecture.None, assemblyName.ProcessorArchitecture);
+            });
+        }
+
         [Fact]
         public void PlatformManifestListsAllFiles()
         {
diff --git a/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj b/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj
index 1854d54a9df..94f546a1cdd 100644
--- a/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj
+++ b/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj
@@ -22,7 +22,7 @@
 
   <ItemGroup>
     <ProjectReference Include="..\..\Mvc.Analyzers\src\Microsoft.AspNetCore.Mvc.Analyzers.csproj" />
-    <ProjectReference Include="..\..\Mvc\ref\Microsoft.AspNetCore.Mvc.csproj" />
+    <ProjectReference Include="..\..\Mvc\src\Microsoft.AspNetCore.Mvc.csproj" />
     <Reference Include="Microsoft.AspNetCore.Analyzer.Testing" />
     <Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
   </ItemGroup>
diff --git a/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj b/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj
index c81ef1db1db..285dfc78662 100644
--- a/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj
+++ b/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj
@@ -20,7 +20,7 @@
 
   <ItemGroup>
     <ProjectReference Include="..\..\Mvc.Api.Analyzers\src\Microsoft.AspNetCore.Mvc.Api.Analyzers.csproj" />
-    <ProjectReference Include="..\..\Mvc\ref\Microsoft.AspNetCore.Mvc.csproj" />
+    <ProjectReference Include="..\..\Mvc\src\Microsoft.AspNetCore.Mvc.csproj" />
     <Reference Include="Microsoft.AspNetCore.Analyzer.Testing" />
     <Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
   </ItemGroup>
diff --git a/src/Shared/ReferenceAssemblyInfo.cs b/src/Shared/ReferenceAssemblyInfo.cs
new file mode 100644
index 00000000000..5906a89a12a
--- /dev/null
+++ b/src/Shared/ReferenceAssemblyInfo.cs
@@ -0,0 +1,10 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+// Reference assemblies should have the ReferenceAssemblyAttribute. 
+[assembly:System.Runtime.CompilerServices.ReferenceAssembly]
+
+// Reference assemblies should have the 0x70 flag which prevents them from loading.
+// This flag sets AssemblyName.ProcessorArchitecture to None. There is no public API for this.
+// Cref https://github.com/dotnet/coreclr/blob/64ca544ecf55490675e72b853e98ebc8cc75a4fe/src/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreCLR.cs#L74
+[assembly:System.Reflection.AssemblyFlags((System.Reflection.AssemblyNameFlags)0x70)]
-- 
GitLab