From 552474f7acbd21a3944cea3d4c9102f582fceef7 Mon Sep 17 00:00:00 2001 From: Josh Schreuder Date: Tue, 14 Jul 2020 16:17:06 +1000 Subject: [PATCH 1/7] Mark Assembly.CodeBase / Assembly.EscapedCodeBase as obsolete (#31127) --- .../Composition/Hosting/AssemblyCatalogTests.cs | 6 ++++++ .../ComponentModel/Design/DesigntimeLicenseContext.cs | 8 ++++---- .../src/System/IO/IsolatedStorage/Helper.Win32Unix.cs | 2 ++ .../System.Reflection.Emit/ref/System.Reflection.Emit.cs | 2 ++ .../Reflection/TypeLoading/Assemblies/RoAssembly.cs | 2 ++ .../tests/src/Tests/RestrictedApis/RestrictedApis.cs | 2 ++ src/libraries/System.Reflection/tests/AssemblyTests.cs | 2 ++ src/libraries/System.Runtime/ref/System.Runtime.cs | 4 ++++ 8 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs b/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs index c8d43e7b10f767..8b983dd5e43f2b 100644 --- a/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs +++ b/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs @@ -36,10 +36,12 @@ public class TestAssemblyFour { } public class AssemblyCatalogTestsHelper { +#pragma warning disable 618 protected string GetAttributedAssemblyCodeBase() { return Assembly.GetExecutingAssembly().CodeBase; } +#pragma warning restore 618 protected Assembly GetAttributedAssembly() { @@ -74,7 +76,9 @@ internal static void Constructor_ValueAsCodebaseArgument_ShouldSetAssemblyProper foreach (var e in expectations) { +#pragma warning disable 618 var catalog = catalogCreator(e.CodeBase); +#pragma warning restore 618 Assert.Same(e, catalog.Assembly); } @@ -694,6 +698,7 @@ public void Constructor8_NullReflectionContextArgument_ShouldThrowArgumentNull() }); } +#pragma warning disable 618 [Fact] public void Constructor8_NullDefinitionOriginArgument_ShouldThrowArgumentNull() { @@ -702,6 +707,7 @@ public void Constructor8_NullDefinitionOriginArgument_ShouldThrowArgumentNull() return new AssemblyCatalog(GetAttributedAssembly().CodeBase, new AssemblyCatalogTestsReflectionContext(), dO); }); } +#pragma warning restore 618 //========================================================================================================================================= // Test cases for Assemblies decorated with the CatalogDiscoveryAttribute diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs index a8d5bb856e9843..fa29018f586aff 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs @@ -79,13 +79,13 @@ public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) { // 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 + // exception on Assembly.Location and we bail out. Catching exceptions here is not a // bad thing. if (asm.IsDynamic) continue; // file://fullpath/foo.exe - string fileName = GetLocalPath(asm.EscapedCodeBase); + string fileName = GetLocalPath(asm.Location); fileName = new FileInfo(fileName).Name; Stream s = asm.GetManifestResourceStream(fileName + ".licenses"); @@ -105,10 +105,10 @@ public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) } else if (!resourceAssembly.IsDynamic) { - // EscapedCodeBase won't be supported by emitted assemblies anyway + // Location won't be supported by emitted assemblies anyway string fileName; - fileName = GetLocalPath(resourceAssembly.EscapedCodeBase); + fileName = GetLocalPath(resourceAssembly.Location); fileName = Path.GetFileName(fileName); string licResourceName = fileName + ".licenses"; diff --git a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs index 692ddc1d7766c4..10b2e4c0b3c7c5 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs +++ b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs @@ -54,7 +54,9 @@ internal static void GetDefaultIdentityAndHash(out object identity, out string h throw new IsolatedStorageException(SR.IsolatedStorage_Init); AssemblyName assemblyName = assembly.GetName(); +#pragma warning disable 618 Uri codeBase = new Uri(assembly.CodeBase!); +#pragma warning restore 618 hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName)!; if (hash != null) diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs index 2031b7df5495a3..59baf31f04774d 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs @@ -9,6 +9,8 @@ namespace System.Reflection.Emit public sealed partial class AssemblyBuilder : System.Reflection.Assembly { internal AssemblyBuilder() { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("CodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", 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; } } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs index b15e44645def21..488d7b1ccdec78 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs @@ -41,8 +41,10 @@ protected RoAssembly(MetadataLoadContext loader, int assemblyFileCount) // Location and codebase public abstract override string Location { get; } +#pragma warning disable 672 public sealed override string CodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase); public sealed override string EscapedCodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase); +#pragma warning restore 672 // Custom Attributes public sealed override IList GetCustomAttributesData() => CustomAttributes.ToReadOnlyCollection(); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs index c8418c5c07159c..133cc2564dbd58 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs @@ -14,8 +14,10 @@ public static void TestRestrictions() { Assembly a = lc.LoadFromAssemblyPath(typeof(TopLevelType).Assembly.Location); +#pragma warning disable 618 Assert.Throws(() => a.CodeBase); Assert.Throws(() => a.EscapedCodeBase); +#pragma warning restore 618 Assert.Throws(() => a.GetObjectData(null, default)); Assert.Throws(() => a.GetSatelliteAssembly(null)); Assert.Throws(() => a.GetSatelliteAssembly(null, null)); diff --git a/src/libraries/System.Reflection/tests/AssemblyTests.cs b/src/libraries/System.Reflection/tests/AssemblyTests.cs index e4033244fd9b90..f337053d9ecac9 100644 --- a/src/libraries/System.Reflection/tests/AssemblyTests.cs +++ b/src/libraries/System.Reflection/tests/AssemblyTests.cs @@ -464,11 +464,13 @@ public void Location_ExecutingAssembly_IsNotNull() Assert.NotNull(Helpers.ExecutingAssembly.Location); } +#pragma warning disable 618 [Fact] public void CodeBase() { Assert.NotEmpty(Helpers.ExecutingAssembly.CodeBase); } +#pragma warning restore 618 [Fact] public void ImageRuntimeVersion() diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 212f8aa9feb67c..a180d9252b4afd 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -7564,10 +7564,14 @@ public AmbiguousMatchException(string? message, System.Exception? inner) { } public abstract partial class Assembly : System.Reflection.ICustomAttributeProvider, System.Runtime.Serialization.ISerializable { protected Assembly() { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("CodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public virtual string? CodeBase { get { throw null; } } public virtual System.Collections.Generic.IEnumerable CustomAttributes { get { throw null; } } public virtual System.Collections.Generic.IEnumerable DefinedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } } public virtual System.Reflection.MethodInfo? EntryPoint { get { throw null; } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("EscapedCodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public virtual string EscapedCodeBase { get { throw null; } } public virtual System.Collections.Generic.IEnumerable ExportedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } } public virtual string? FullName { get { throw null; } } From 4c9adccc0954d8b4f8cff5c3e42ca404aaa53d8b Mon Sep 17 00:00:00 2001 From: Josh Schreuder Date: Fri, 17 Jul 2020 20:52:20 +1000 Subject: [PATCH 2/7] Updates based on review feedback --- .../Design/DesigntimeLicenseContext.cs | 24 +++++++------------ .../TypeLoading/Assemblies/RoAssembly.cs | 6 +++-- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs index fa29018f586aff..f654e4e8aa8fea 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs @@ -77,16 +77,13 @@ public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) // 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.Location and we bail out. Catching exceptions here is not a - // bad thing. - if (asm.IsDynamic) + // Assemblies loaded in memory return empty string from Location. + // The code below throws an exception if this happens. + // Catching exceptions here is not a bad thing. + if (asm.Location == string.Empty) continue; - // file://fullpath/foo.exe - string fileName = GetLocalPath(asm.Location); - fileName = new FileInfo(fileName).Name; + string fileName = new FileInfo(asm.Location).Name; Stream s = asm.GetManifestResourceStream(fileName + ".licenses"); if (s == null) @@ -103,14 +100,11 @@ public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) } } } - else if (!resourceAssembly.IsDynamic) + // Location is not supported by emitted assemblies and this will throw an exception + // down below. + else if (!resourceAssembly.IsDynamic && resourceAssembly.Location != string.Empty) { - // Location won't be supported by emitted assemblies anyway - string fileName; - - fileName = GetLocalPath(resourceAssembly.Location); - - fileName = Path.GetFileName(fileName); + string fileName = Path.GetFileName(resourceAssembly.Location); string licResourceName = fileName + ".licenses"; // First try the filename diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs index 488d7b1ccdec78..0b6d69826b9239 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs @@ -41,10 +41,12 @@ protected RoAssembly(MetadataLoadContext loader, int assemblyFileCount) // Location and codebase public abstract override string Location { get; } -#pragma warning disable 672 + [ComponentModel.EditorBrowsableAttribute(ComponentModel.EditorBrowsableState.Never)] + [ObsoleteAttribute("CodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public sealed override string CodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase); + [ComponentModel.EditorBrowsableAttribute(ComponentModel.EditorBrowsableState.Never)] + [ObsoleteAttribute("EscapedCodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public sealed override string EscapedCodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase); -#pragma warning restore 672 // Custom Attributes public sealed override IList GetCustomAttributesData() => CustomAttributes.ToReadOnlyCollection(); From 7f6aa6c5e663f37c99507e23a2a0168f62939cb0 Mon Sep 17 00:00:00 2001 From: Josh Schreuder Date: Sun, 19 Jul 2020 15:05:39 +1000 Subject: [PATCH 3/7] Update to use common Obsoletions class --- docs/project/list-of-obsoletions.md | 1 + src/libraries/Common/src/System/Obsoletions.cs | 3 +++ .../Composition/Hosting/AssemblyCatalogTests.cs | 12 ++++++------ .../System/IO/IsolatedStorage/Helper.Win32Unix.cs | 4 ++-- .../ref/System.Reflection.Emit.cs | 3 +-- .../ref/System.Reflection.Emit.csproj | 1 + .../src/System.Reflection.MetadataLoadContext.csproj | 1 + .../Reflection/TypeLoading/Assemblies/RoAssembly.cs | 6 ++---- .../tests/src/Tests/RestrictedApis/RestrictedApis.cs | 4 ++-- .../System.Reflection/tests/AssemblyTests.cs | 4 ++-- src/libraries/System.Runtime/ref/System.Runtime.cs | 6 ++---- .../System.Runtime/ref/System.Runtime.csproj | 3 +++ 12 files changed, 26 insertions(+), 22 deletions(-) diff --git a/docs/project/list-of-obsoletions.md b/docs/project/list-of-obsoletions.md index 3b7d6696c62da6..81e8cdfeec3e9b 100644 --- a/docs/project/list-of-obsoletions.md +++ b/docs/project/list-of-obsoletions.md @@ -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`__ | `CodeBase` and `EscapedCodeBase` are only included for .NET Framework compatibility. Use `Location` instead. | diff --git a/src/libraries/Common/src/System/Obsoletions.cs b/src/libraries/Common/src/System/Obsoletions.cs index a7c5582f7bd8d5..396904c1ca94ff 100644 --- a/src/libraries/Common/src/System/Obsoletions.cs +++ b/src/libraries/Common/src/System/Obsoletions.cs @@ -39,5 +39,8 @@ internal static class Obsoletions 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 = "CodeBase and EscapedCodeBase are only included for .NET Framework compatibility. Use Location instead."; + internal const string CodeBaseDiagId = "SYSLIB0012"; } } diff --git a/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs b/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs index 8b983dd5e43f2b..333dd8e473bb6d 100644 --- a/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs +++ b/src/libraries/System.ComponentModel.Composition/tests/System/ComponentModel/Composition/Hosting/AssemblyCatalogTests.cs @@ -36,12 +36,12 @@ public class TestAssemblyFour { } public class AssemblyCatalogTestsHelper { -#pragma warning disable 618 +#pragma warning disable SYSLIB0012 protected string GetAttributedAssemblyCodeBase() { return Assembly.GetExecutingAssembly().CodeBase; } -#pragma warning restore 618 +#pragma warning restore SYSLIB0012 protected Assembly GetAttributedAssembly() { @@ -76,9 +76,9 @@ internal static void Constructor_ValueAsCodebaseArgument_ShouldSetAssemblyProper foreach (var e in expectations) { -#pragma warning disable 618 +#pragma warning disable SYSLIB0012 var catalog = catalogCreator(e.CodeBase); -#pragma warning restore 618 +#pragma warning restore SYSLIB0012 Assert.Same(e, catalog.Assembly); } @@ -698,7 +698,7 @@ public void Constructor8_NullReflectionContextArgument_ShouldThrowArgumentNull() }); } -#pragma warning disable 618 +#pragma warning disable SYSLIB0012 [Fact] public void Constructor8_NullDefinitionOriginArgument_ShouldThrowArgumentNull() { @@ -707,7 +707,7 @@ public void Constructor8_NullDefinitionOriginArgument_ShouldThrowArgumentNull() return new AssemblyCatalog(GetAttributedAssembly().CodeBase, new AssemblyCatalogTestsReflectionContext(), dO); }); } -#pragma warning restore 618 +#pragma warning restore SYSLIB0012 //========================================================================================================================================= // Test cases for Assemblies decorated with the CatalogDiscoveryAttribute diff --git a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs index 10b2e4c0b3c7c5..33e611115fa28e 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs +++ b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs @@ -54,9 +54,9 @@ internal static void GetDefaultIdentityAndHash(out object identity, out string h throw new IsolatedStorageException(SR.IsolatedStorage_Init); AssemblyName assemblyName = assembly.GetName(); -#pragma warning disable 618 +#pragma warning disable SYSLIB0012 Uri codeBase = new Uri(assembly.CodeBase!); -#pragma warning restore 618 +#pragma warning restore SYSLIB0012 hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName)!; if (hash != null) diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs index 59baf31f04774d..a57d9893164ea7 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs @@ -9,8 +9,7 @@ namespace System.Reflection.Emit public sealed partial class AssemblyBuilder : System.Reflection.Assembly { internal AssemblyBuilder() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.ObsoleteAttribute("CodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ObsoleteAttribute(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public override string? CodeBase { get { throw null; } } public override System.Reflection.MethodInfo? EntryPoint { get { throw null; } } public override string? FullName { get { throw null; } } diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj index be3da7e1429229..43eb97793cc6aa 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj @@ -5,6 +5,7 @@ + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj index 7e70cb22fd6560..7cee550642984c 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj @@ -144,6 +144,7 @@ + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs index 0b6d69826b9239..9a6b5e64e768e7 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs @@ -41,11 +41,9 @@ protected RoAssembly(MetadataLoadContext loader, int assemblyFileCount) // Location and codebase public abstract override string Location { get; } - [ComponentModel.EditorBrowsableAttribute(ComponentModel.EditorBrowsableState.Never)] - [ObsoleteAttribute("CodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public sealed override string CodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase); - [ComponentModel.EditorBrowsableAttribute(ComponentModel.EditorBrowsableState.Never)] - [ObsoleteAttribute("EscapedCodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public sealed override string EscapedCodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase); // Custom Attributes diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs index 133cc2564dbd58..f154f0987723ff 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/RestrictedApis/RestrictedApis.cs @@ -14,10 +14,10 @@ public static void TestRestrictions() { Assembly a = lc.LoadFromAssemblyPath(typeof(TopLevelType).Assembly.Location); -#pragma warning disable 618 +#pragma warning disable SYSLIB0012 Assert.Throws(() => a.CodeBase); Assert.Throws(() => a.EscapedCodeBase); -#pragma warning restore 618 +#pragma warning restore SYSLIB0012 Assert.Throws(() => a.GetObjectData(null, default)); Assert.Throws(() => a.GetSatelliteAssembly(null)); Assert.Throws(() => a.GetSatelliteAssembly(null, null)); diff --git a/src/libraries/System.Reflection/tests/AssemblyTests.cs b/src/libraries/System.Reflection/tests/AssemblyTests.cs index f337053d9ecac9..8f7384f685f69d 100644 --- a/src/libraries/System.Reflection/tests/AssemblyTests.cs +++ b/src/libraries/System.Reflection/tests/AssemblyTests.cs @@ -464,13 +464,13 @@ public void Location_ExecutingAssembly_IsNotNull() Assert.NotNull(Helpers.ExecutingAssembly.Location); } -#pragma warning disable 618 +#pragma warning disable SYSLIB0012 [Fact] public void CodeBase() { Assert.NotEmpty(Helpers.ExecutingAssembly.CodeBase); } -#pragma warning restore 618 +#pragma warning restore SYSLIB0012 [Fact] public void ImageRuntimeVersion() diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index a180d9252b4afd..a7b7f394e3e59f 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -7564,14 +7564,12 @@ public AmbiguousMatchException(string? message, System.Exception? inner) { } public abstract partial class Assembly : System.Reflection.ICustomAttributeProvider, System.Runtime.Serialization.ISerializable { protected Assembly() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.ObsoleteAttribute("CodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ObsoleteAttribute(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public virtual string? CodeBase { get { throw null; } } public virtual System.Collections.Generic.IEnumerable CustomAttributes { get { throw null; } } public virtual System.Collections.Generic.IEnumerable DefinedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } } public virtual System.Reflection.MethodInfo? EntryPoint { get { throw null; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.ObsoleteAttribute("EscapedCodeBase is only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "TODO", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ObsoleteAttribute(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public virtual string EscapedCodeBase { get { throw null; } } public virtual System.Collections.Generic.IEnumerable ExportedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } } public virtual string? FullName { get { throw null; } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.csproj b/src/libraries/System.Runtime/ref/System.Runtime.csproj index 9a05ef6d40318e..1feeb76c2c419e 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.csproj +++ b/src/libraries/System.Runtime/ref/System.Runtime.csproj @@ -13,4 +13,7 @@ + + + \ No newline at end of file From be913f2eeab80c9920d57dc27daff1e1b91852cd Mon Sep 17 00:00:00 2001 From: Josh Schreuder Date: Sun, 19 Jul 2020 17:09:53 +1000 Subject: [PATCH 4/7] Updates to fix path reference and fix older runtime builds --- .../System.Reflection.Emit/ref/System.Reflection.Emit.csproj | 2 +- .../System/Reflection/TypeLoading/Assemblies/RoAssembly.cs | 4 ++++ src/libraries/System.Runtime/ref/System.Runtime.csproj | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj index 43eb97793cc6aa..df12244a6038db 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs index 9a6b5e64e768e7..ca133f247c7d47 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs @@ -41,9 +41,13 @@ protected RoAssembly(MetadataLoadContext loader, int assemblyFileCount) // 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 diff --git a/src/libraries/System.Runtime/ref/System.Runtime.csproj b/src/libraries/System.Runtime/ref/System.Runtime.csproj index 1feeb76c2c419e..2d91af4f9d7fc1 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.csproj +++ b/src/libraries/System.Runtime/ref/System.Runtime.csproj @@ -14,6 +14,6 @@ - + \ No newline at end of file From 43a8c26a41a452fc59d70c51c98a8451c401ea5c Mon Sep 17 00:00:00 2001 From: Josh Schreuder Date: Sun, 19 Jul 2020 17:22:42 +1000 Subject: [PATCH 5/7] Use string literals for obsoletions in ref files rather than linking common class --- .../System.Reflection.Emit/ref/System.Reflection.Emit.cs | 2 +- .../System.Reflection.Emit/ref/System.Reflection.Emit.csproj | 1 - src/libraries/System.Runtime/ref/System.Runtime.cs | 4 ++-- src/libraries/System.Runtime/ref/System.Runtime.csproj | 3 --- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs index a57d9893164ea7..0e07e91fa982d8 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs @@ -9,7 +9,7 @@ namespace System.Reflection.Emit public sealed partial class AssemblyBuilder : System.Reflection.Assembly { internal AssemblyBuilder() { } - [System.ObsoleteAttribute(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] + [Obsolete("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; } } diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj index df12244a6038db..be3da7e1429229 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.csproj @@ -5,7 +5,6 @@ - diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index a7b7f394e3e59f..a4a16a66064ee4 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -7564,12 +7564,12 @@ public AmbiguousMatchException(string? message, System.Exception? inner) { } public abstract partial class Assembly : System.Reflection.ICustomAttributeProvider, System.Runtime.Serialization.ISerializable { protected Assembly() { } - [System.ObsoleteAttribute(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] + [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 CustomAttributes { get { throw null; } } public virtual System.Collections.Generic.IEnumerable DefinedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } } public virtual System.Reflection.MethodInfo? EntryPoint { get { throw null; } } - [System.ObsoleteAttribute(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] + [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 ExportedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } } public virtual string? FullName { get { throw null; } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.csproj b/src/libraries/System.Runtime/ref/System.Runtime.csproj index 2d91af4f9d7fc1..9a05ef6d40318e 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.csproj +++ b/src/libraries/System.Runtime/ref/System.Runtime.csproj @@ -13,7 +13,4 @@ - - - \ No newline at end of file From 7eec075309dc2e68fd231c5dbe9d5292b320c1f3 Mon Sep 17 00:00:00 2001 From: Josh Schreuder Date: Sun, 26 Jul 2020 13:00:17 +1000 Subject: [PATCH 6/7] Fix ObsoleteAttribute ref references and assembly location checks in TypeConverter --- .../Design/DesigntimeLicenseContext.cs | 61 ++++++++++--------- .../ref/System.Reflection.Emit.cs | 4 +- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs index f654e4e8aa8fea..c650b38372f750 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs @@ -78,12 +78,11 @@ public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { // Assemblies loaded in memory return empty string from Location. - // The code below throws an exception if this happens. - // Catching exceptions here is not a bad thing. - if (asm.Location == string.Empty) + string location = asm.Location; + if (location == string.Empty) continue; - string fileName = new FileInfo(asm.Location).Name; + string fileName = new FileInfo(location).Name; Stream s = asm.GetManifestResourceStream(fileName + ".licenses"); if (s == null) @@ -100,41 +99,43 @@ public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly) } } } - // Location is not supported by emitted assemblies and this will throw an exception - // down below. - else if (!resourceAssembly.IsDynamic && resourceAssembly.Location != string.Empty) + else { - string fileName = Path.GetFileName(resourceAssembly.Location); - 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()) + { + 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) { - resolvedName = existingName; - break; + 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]; diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs index 0e07e91fa982d8..f5b245a5cee04e 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs @@ -9,11 +9,11 @@ namespace System.Reflection.Emit public sealed partial class AssemblyBuilder : System.Reflection.Assembly { internal AssemblyBuilder() { } - [Obsolete("CodeBase and EscapedCodeBase are only included for .NET Framework compatibility. Use Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [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; } } From 50b7bfb7976df646154be23b72b0d7654325de92 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sun, 26 Jul 2020 09:19:49 -0700 Subject: [PATCH 7/7] Apply suggestions from code review --- docs/project/list-of-obsoletions.md | 2 +- src/libraries/Common/src/System/Obsoletions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/project/list-of-obsoletions.md b/docs/project/list-of-obsoletions.md index 81e8cdfeec3e9b..35bae5551e4d11 100644 --- a/docs/project/list-of-obsoletions.md +++ b/docs/project/list-of-obsoletions.md @@ -24,4 +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`__ | `CodeBase` and `EscapedCodeBase` are only included for .NET Framework compatibility. Use `Location` instead. | +| __`SYSLIB0012`__ | Use Location instead. | diff --git a/src/libraries/Common/src/System/Obsoletions.cs b/src/libraries/Common/src/System/Obsoletions.cs index 396904c1ca94ff..6b08f78ce49180 100644 --- a/src/libraries/Common/src/System/Obsoletions.cs +++ b/src/libraries/Common/src/System/Obsoletions.cs @@ -40,7 +40,7 @@ internal static class Obsoletions 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 = "CodeBase and EscapedCodeBase are only included for .NET Framework compatibility. Use Location instead."; + internal const string CodeBaseMessage = "Use Location instead."; internal const string CodeBaseDiagId = "SYSLIB0012"; } }