Mark Assembly.CodeBase / Assembly.EscapedCodeBase as obsolete (#31127) (#39261)
authorJosh Schreuder <joshschreuder@gmail.com>
Sun, 26 Jul 2020 18:38:15 +0000 (04:38 +1000)
committerGitHub <noreply@github.com>
Sun, 26 Jul 2020 18:38:15 +0000 (11:38 -0700)
docs/project/list-of-obsoletions.md
src/libraries/Common/src/System/Obsoletions.cs
src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs
src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs
src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs
src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs
src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj
src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs
src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs
src/libraries/System.Reflection/tests/AssemblyTests.cs
src/libraries/System.Runtime/ref/System.Runtime.cs

index 3b7d669..35bae55 100644 (file)
@@ -24,3 +24,4 @@ Currently the identifiers `SYSLIB0001` through `SYSLIB0999` are carved out for o
 |  __`SYSLIB0009`__ | The AuthenticationManager Authenticate and PreAuthenticate methods are not supported and throw PlatformNotSupportedException. |
 |  __`SYSLIB0010`__ | This Remoting API is not supported and throws PlatformNotSupportedException. |
 |  __`SYSLIB0011`__ | `BinaryFormatter` serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for recommended alternatives. |
+|  __`SYSLIB0012`__ | Use Location instead. |
index a7c5582..6b08f78 100644 (file)
@@ -39,5 +39,8 @@ namespace System
 
         internal const string BinaryFormatterMessage = "BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.";
         internal const string BinaryFormatterDiagId = "SYSLIB0011";
+
+        internal const string CodeBaseMessage = "Use Location instead.";
+        internal const string CodeBaseDiagId = "SYSLIB0012";
     }
 }
index c8d43e7..333dd8e 100644 (file)
@@ -36,10 +36,12 @@ namespace System.ComponentModel.Composition
 
     public class AssemblyCatalogTestsHelper
     {
+#pragma warning disable SYSLIB0012
         protected string GetAttributedAssemblyCodeBase()
         {
             return Assembly.GetExecutingAssembly().CodeBase;
         }
+#pragma warning restore SYSLIB0012
 
         protected Assembly GetAttributedAssembly()
         {
@@ -74,7 +76,9 @@ namespace System.ComponentModel.Composition
 
             foreach (var e in expectations)
             {
+#pragma warning disable SYSLIB0012
                 var catalog = catalogCreator(e.CodeBase);
+#pragma warning restore SYSLIB0012
 
                 Assert.Same(e, catalog.Assembly);
             }
@@ -694,6 +698,7 @@ namespace System.ComponentModel.Composition
             });
         }
 
+#pragma warning disable SYSLIB0012
         [Fact]
         public void Constructor8_NullDefinitionOriginArgument_ShouldThrowArgumentNull()
         {
@@ -702,6 +707,7 @@ namespace System.ComponentModel.Composition
                 return new AssemblyCatalog(GetAttributedAssembly().CodeBase, new AssemblyCatalogTestsReflectionContext(), dO);
             });
         }
+#pragma warning restore SYSLIB0012
 
         //=========================================================================================================================================
         //  Test cases for Assemblies decorated with the CatalogDiscoveryAttribute
index a8d5bb8..c650b38 100644 (file)
@@ -77,16 +77,12 @@ namespace System.ComponentModel.Design
                     // try everything.
                     foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
                     {
-                        // Though, I could not repro this, we seem to be hitting an AssemblyBuilder
-                        // when walking through all the assemblies in the current app domain. This throws an
-                        // exception on Assembly.CodeBase and we bail out. Catching exceptions here is not a
-                        // bad thing.
-                        if (asm.IsDynamic)
+                        // Assemblies loaded in memory return empty string from Location.
+                        string location = asm.Location;
+                        if (location == string.Empty)
                             continue;
 
-                        // file://fullpath/foo.exe
-                        string fileName = GetLocalPath(asm.EscapedCodeBase);
-                        fileName = new FileInfo(fileName).Name;
+                        string fileName = new FileInfo(location).Name;
 
                         Stream s = asm.GetManifestResourceStream(fileName + ".licenses");
                         if (s == null)
@@ -103,44 +99,43 @@ namespace System.ComponentModel.Design
                         }
                     }
                 }
-                else if (!resourceAssembly.IsDynamic)
+                else
                 {
-                    // EscapedCodeBase won't be supported by emitted assemblies anyway
-                    string fileName;
-
-                    fileName = GetLocalPath(resourceAssembly.EscapedCodeBase);
-
-                    fileName = Path.GetFileName(fileName);
-                    string licResourceName = fileName + ".licenses";
-
-                    // First try the filename
-                    Stream s = resourceAssembly.GetManifestResourceStream(licResourceName);
-                    if (s == null)
+                    string location = resourceAssembly.Location;
+                    if (location != string.Empty)
                     {
-                        string resolvedName = null;
-                        CompareInfo comparer = CultureInfo.InvariantCulture.CompareInfo;
-                        string shortAssemblyName = resourceAssembly.GetName().Name;
-                        // If the assembly has been renamed, we try our best to find a good match in the available resources
-                        // by looking at the assembly name (which doesn't change even after a file rename) + ".exe.licenses" or + ".dll.licenses"
-                        foreach (string existingName in resourceAssembly.GetManifestResourceNames())
+                        string fileName = Path.GetFileName(location);
+                        string licResourceName = fileName + ".licenses";
+
+                        // First try the filename
+                        Stream s = resourceAssembly.GetManifestResourceStream(licResourceName);
+                        if (s == null)
                         {
-                            if (comparer.Compare(existingName, licResourceName, CompareOptions.IgnoreCase) == 0 ||
-                             comparer.Compare(existingName, shortAssemblyName + ".exe.licenses", CompareOptions.IgnoreCase) == 0 ||
-                             comparer.Compare(existingName, shortAssemblyName + ".dll.licenses", CompareOptions.IgnoreCase) == 0)
+                            string resolvedName = null;
+                            CompareInfo comparer = CultureInfo.InvariantCulture.CompareInfo;
+                            string shortAssemblyName = resourceAssembly.GetName().Name;
+                            // If the assembly has been renamed, we try our best to find a good match in the available resources
+                            // by looking at the assembly name (which doesn't change even after a file rename) + ".exe.licenses" or + ".dll.licenses"
+                            foreach (string existingName in resourceAssembly.GetManifestResourceNames())
                             {
-                                resolvedName = existingName;
-                                break;
+                                if (comparer.Compare(existingName, licResourceName, CompareOptions.IgnoreCase) == 0 ||
+                                 comparer.Compare(existingName, shortAssemblyName + ".exe.licenses", CompareOptions.IgnoreCase) == 0 ||
+                                 comparer.Compare(existingName, shortAssemblyName + ".dll.licenses", CompareOptions.IgnoreCase) == 0)
+                                {
+                                    resolvedName = existingName;
+                                    break;
+                                }
+                            }
+                            if (resolvedName != null)
+                            {
+                                s = resourceAssembly.GetManifestResourceStream(resolvedName);
                             }
                         }
-                        if (resolvedName != null)
+                        if (s != null)
                         {
-                            s = resourceAssembly.GetManifestResourceStream(resolvedName);
+                            DesigntimeLicenseContextSerializer.Deserialize(s, fileName.ToUpperInvariant(), this);
                         }
                     }
-                    if (s != null)
-                    {
-                        DesigntimeLicenseContextSerializer.Deserialize(s, fileName.ToUpperInvariant(), this);
-                    }
                 }
             }
             return (string)_savedLicenseKeys[type.AssemblyQualifiedName];
index 692ddc1..33e6111 100644 (file)
@@ -54,7 +54,9 @@ namespace System.IO.IsolatedStorage
                 throw new IsolatedStorageException(SR.IsolatedStorage_Init);
 
             AssemblyName assemblyName = assembly.GetName();
+#pragma warning disable SYSLIB0012
             Uri codeBase = new Uri(assembly.CodeBase!);
+#pragma warning restore SYSLIB0012
 
             hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName)!;
             if (hash != null)
index 2031b7d..f5b245a 100644 (file)
@@ -9,10 +9,11 @@ namespace System.Reflection.Emit
     public sealed partial class AssemblyBuilder : System.Reflection.Assembly
     {
         internal AssemblyBuilder() { }
+        [System.ObsoleteAttribute("CodeBase and EscapedCodeBase are only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
         public override string? CodeBase { get { throw null; } }
         public override System.Reflection.MethodInfo? EntryPoint { get { throw null; } }
         public override string? FullName { get { throw null; } }
-        [Obsolete("The Global Assembly Cache is not supported.", DiagnosticId = "SYSLIB0005", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
+        [System.ObsoleteAttribute("The Global Assembly Cache is not supported.", DiagnosticId = "SYSLIB0005", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
         public override bool GlobalAssemblyCache { get { throw null; } }
         public override long HostContext { get { throw null; } }
         public override string ImageRuntimeVersion { get { throw null; } }
index 7e70cb2..7cee550 100644 (file)
     <Compile Include="System\Reflection\TypeLoading\Types\RoType.GetInterface.cs" />
     <Compile Include="System\Reflection\TypeLoading\Types\RoType.TypeClassification.cs" />
     <Compile Include="System\Reflection\TypeLoading\Types\RoWrappedType.cs" />
+    <Compile Include="$(CommonPath)System\Obsoletions.cs" Link="Common\System\Obsoletions.cs" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)' or
                         '$(TargetFramework)' == 'netcoreapp3.0'">
index b15e446..ca133f2 100644 (file)
@@ -41,7 +41,13 @@ namespace System.Reflection.TypeLoading
 
         // Location and codebase
         public abstract override string Location { get; }
+#if NET50_OBSOLETIONS
+        [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
+#endif
         public sealed override string CodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase);
+#if NET50_OBSOLETIONS
+        [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
+#endif
         public sealed override string EscapedCodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase);
 
         // Custom Attributes
index c8418c5..f154f09 100644 (file)
@@ -14,8 +14,10 @@ namespace System.Reflection.Tests
             {
                 Assembly a = lc.LoadFromAssemblyPath(typeof(TopLevelType).Assembly.Location);
 
+#pragma warning disable SYSLIB0012
                 Assert.Throws<NotSupportedException>(() => a.CodeBase);
                 Assert.Throws<NotSupportedException>(() => a.EscapedCodeBase);
+#pragma warning restore SYSLIB0012
                 Assert.Throws<NotSupportedException>(() => a.GetObjectData(null, default));
                 Assert.Throws<NotSupportedException>(() => a.GetSatelliteAssembly(null));
                 Assert.Throws<NotSupportedException>(() => a.GetSatelliteAssembly(null, null));
index e403324..8f7384f 100644 (file)
@@ -464,11 +464,13 @@ namespace System.Reflection.Tests
             Assert.NotNull(Helpers.ExecutingAssembly.Location);
         }
 
+#pragma warning disable SYSLIB0012
         [Fact]
         public void CodeBase()
         {
             Assert.NotEmpty(Helpers.ExecutingAssembly.CodeBase);
         }
+#pragma warning restore SYSLIB0012
 
         [Fact]
         public void ImageRuntimeVersion()
index 212f8aa..a4a16a6 100644 (file)
@@ -7564,10 +7564,12 @@ namespace System.Reflection
     public abstract partial class Assembly : System.Reflection.ICustomAttributeProvider, System.Runtime.Serialization.ISerializable
     {
         protected Assembly() { }
+        [System.ObsoleteAttribute("CodeBase and EscapedCodeBase are only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
         public virtual string? CodeBase { get { throw null; } }
         public virtual System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> CustomAttributes { get { throw null; } }
         public virtual System.Collections.Generic.IEnumerable<System.Reflection.TypeInfo> DefinedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } }
         public virtual System.Reflection.MethodInfo? EntryPoint { get { throw null; } }
+        [System.ObsoleteAttribute("CodeBase and EscapedCodeBase are only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
         public virtual string EscapedCodeBase { get { throw null; } }
         public virtual System.Collections.Generic.IEnumerable<System.Type> ExportedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } }
         public virtual string? FullName { get { throw null; } }