Add RequiresAssemblyFiles attribute (#56196)
authorAndy Gocke <angocke@microsoft.com>
Fri, 30 Jul 2021 20:20:57 +0000 (13:20 -0700)
committerGitHub <noreply@github.com>
Fri, 30 Jul 2021 20:20:57 +0000 (13:20 -0700)
This PR annotates every API doc'd as having different
behavior in single-file publishing with RequiresAssemblyFiles.
Some APIs might be special-cased by the analyzer to produce
special messages, but RAF is useful for visual inspection
of the APIs. Module.Name and .FullyQualifiedName were also
unannotated.

22 files changed:
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs
src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs
src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/LicFileLicenseProvider.cs
src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs
src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs
src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
src/libraries/System.Private.CoreLib/src/System/Reflection/Module.cs
src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingModule.cs
src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs
src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/Ecma/EcmaAssembly.ManifestResources.cs
src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.Modules.cs
src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs
src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/Ecma/EcmaModule.GetTypeCore.cs
src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoModule.cs
src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoResourceModule.cs
src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Module/MultiModuleTests.cs
src/libraries/System.Runtime/ref/System.Runtime.cs
src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs
src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs

index 6f34f7d..0914c0c 100644 (file)
@@ -77,11 +77,13 @@ namespace System.Reflection.Emit
             throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
         }
 
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override FileStream GetFile(string name)
         {
             throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
         }
 
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override FileStream[] GetFiles(bool getResourceModules)
         {
             throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
@@ -104,7 +106,7 @@ namespace System.Reflection.Emit
 
         public override string Location => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
 
-        [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
 
         [RequiresUnreferencedCode("Types might be removed")]
index c1c243b..230bb06 100644 (file)
@@ -706,6 +706,7 @@ namespace System.Reflection.Emit
             return GetType(parameters, baseType);
         }
 
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public override string FullyQualifiedName => _moduleData._moduleName;
 
         [RequiresUnreferencedCode("Trimming changes metadata tokens")]
@@ -785,6 +786,7 @@ namespace System.Reflection.Emit
 
         public override string ScopeName => InternalModule.ScopeName;
 
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public override string Name => InternalModule.Name;
 
         public override Assembly Assembly => _assemblyBuilder;
index cb7bd41..5a5fd3e 100644 (file)
@@ -83,7 +83,7 @@ namespace System.Reflection
             return null;
         }
 
-        [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override string? CodeBase
         {
             get
@@ -372,6 +372,7 @@ namespace System.Reflection
 
         // Returns the file in the File table of the manifest that matches the
         // given name.  (Name should not include path.)
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override FileStream? GetFile(string name)
         {
             if (Location.Length == 0)
@@ -389,6 +390,7 @@ namespace System.Reflection
                                   FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false);
         }
 
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override FileStream[] GetFiles(bool getResourceModules)
         {
             if (Location.Length == 0)
index a85a222..a5aad80 100644 (file)
@@ -441,6 +441,7 @@ namespace System.Reflection
             return retType;
         }
 
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         internal string GetFullyQualifiedName()
         {
             string? fullyQualifiedName = null;
@@ -449,9 +450,10 @@ namespace System.Reflection
             return fullyQualifiedName!;
         }
 
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public override string FullyQualifiedName => GetFullyQualifiedName();
 
-      [RequiresUnreferencedCode("Types might be removed")]
+        [RequiresUnreferencedCode("Types might be removed")]
         public override Type[] GetTypes()
         {
             return GetTypes(this);
@@ -518,6 +520,7 @@ namespace System.Reflection
             }
         }
 
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public override string Name
         {
             get
index cd420c9..e5ce14b 100644 (file)
@@ -3,6 +3,7 @@
 
 using System.ComponentModel.Design;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.IO;
 
@@ -40,6 +41,10 @@ namespace System.ComponentModel
         /// <summary>
         /// Gets a license for the instance of the component and determines if it is valid.
         /// </summary>
+        [UnconditionalSuppressMessage("SingleFile", "IL3002:RequiresAssemblyFiles",
+            Justification = "Only used for when Location is non-empty")]
+        [UnconditionalSuppressMessage("SingleFile", "IL3000:RequiresAssemblyFiles",
+            Justification = "Location is checked for empty")]
         public override License? GetLicense(LicenseContext context, Type type, object? instance, bool allowExceptions)
         {
             LicFileLicense? lic = null;
@@ -69,30 +74,33 @@ namespace System.ComponentModel
                         }
                     }
 
-                    if (modulePath == null)
+                    if (type.Assembly.Location.Length != 0)
                     {
-                        modulePath = type.Module.FullyQualifiedName;
-                    }
+                        if (modulePath == null)
+                        {
+                            modulePath = type.Module.FullyQualifiedName;
+                        }
 
-                    string? moduleDir = Path.GetDirectoryName(modulePath);
-                    string licenseFile = moduleDir + "\\" + type.FullName + ".lic";
+                        string? moduleDir = Path.GetDirectoryName(modulePath);
+                        string licenseFile = moduleDir + "\\" + type.FullName + ".lic";
 
-                    Debug.WriteLine($"Looking for license in: {licenseFile}");
-                    if (File.Exists(licenseFile))
-                    {
-                        Stream licStream = new FileStream(licenseFile, FileMode.Open, FileAccess.Read, FileShare.Read);
-                        StreamReader sr = new StreamReader(licStream);
-                        string? s = sr.ReadLine();
-                        sr.Close();
-                        if (IsKeyValid(s, type))
+                        Debug.WriteLine($"Looking for license in: {licenseFile}");
+                        if (File.Exists(licenseFile))
                         {
-                            lic = new LicFileLicense(this, GetKey(type));
+                            Stream licStream = new FileStream(licenseFile, FileMode.Open, FileAccess.Read, FileShare.Read);
+                            StreamReader sr = new StreamReader(licStream);
+                            string? s = sr.ReadLine();
+                            sr.Close();
+                            if (IsKeyValid(s, type))
+                            {
+                                lic = new LicFileLicense(this, GetKey(type));
+                            }
                         }
-                    }
 
-                    if (lic != null)
-                    {
-                        context!.SetSavedLicenseKey(type, lic.LicenseKey);
+                        if (lic != null)
+                        {
+                            context!.SetSavedLicenseKey(type, lic.LicenseKey);
+                        }
                     }
                 }
             }
index a92612c..747815c 100644 (file)
@@ -31,6 +31,8 @@ namespace System.Configuration
 
         [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
             Justification = "Code handles single file case")]
+        [UnconditionalSuppressMessage("SingleFile", "IL3002: RequiresAssemblyFiles on Module.Name",
+            Justification = "Code handles single file case")]
         private ClientConfigPaths(string exePath, bool includeUserConfig)
         {
             _includesUserConfig = includeUserConfig;
@@ -222,6 +224,8 @@ namespace System.Configuration
         // The evidence we use, in priority order, is Strong Name, Url and Exe Path. If one of
         // these is found, we compute a SHA1 hash of it and return a suffix based on that.
         // If none is found, we return null.
+        [UnconditionalSuppressMessage("SingleFile", "IL3002: RequiresAssemblyFiles on Module.Name",
+            Justification = "Code handles single file case")]
         private static string GetTypeAndHashSuffix(string exePath, bool isSingleFile)
         {
             Assembly assembly = Assembly.GetEntryAssembly();
index 5b5035b..3612e75 100644 (file)
@@ -81,7 +81,9 @@ namespace System.Reflection
         [RequiresUnreferencedCode("Types might be removed")]
         public virtual Type[] GetForwardedTypes() { throw NotImplemented.ByDesign; }
 
-        [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        internal const string ThrowingMessageInRAF = "This member throws an exception for assemblies embedded in a single-file app";
+
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public virtual string? CodeBase => throw NotImplemented.ByDesign;
         public virtual MethodInfo? EntryPoint => throw NotImplemented.ByDesign;
         public virtual string? FullName => throw NotImplemented.ByDesign;
@@ -116,7 +118,7 @@ namespace System.Reflection
         public virtual object[] GetCustomAttributes(bool inherit) { throw NotImplemented.ByDesign; }
         public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
 
-        [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public virtual string EscapedCodeBase => AssemblyName.EscapeCodeBase(CodeBase);
 
         [RequiresUnreferencedCode("Assembly.CreateInstance is not supported with trimming. Use Type.GetType instead.")]
@@ -153,9 +155,11 @@ namespace System.Reflection
         public virtual Assembly GetSatelliteAssembly(CultureInfo culture) { throw NotImplemented.ByDesign; }
         public virtual Assembly GetSatelliteAssembly(CultureInfo culture, Version? version) { throw NotImplemented.ByDesign; }
 
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public virtual FileStream? GetFile(string name) { throw NotImplemented.ByDesign; }
-        [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public virtual FileStream[] GetFiles() => GetFiles(getResourceModules: false);
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public virtual FileStream[] GetFiles(bool getResourceModules) { throw NotImplemented.ByDesign; }
 
         public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { throw NotImplemented.ByDesign; }
index dc77c94..631b6ea 100644 (file)
@@ -8,7 +8,7 @@ namespace System.Reflection.Emit
 {
     public sealed partial class AssemblyBuilder : Assembly
     {
-        [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
         public override string Location => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
         public override MethodInfo? EntryPoint => null;
@@ -18,9 +18,11 @@ namespace System.Reflection.Emit
         public override Type[] GetExportedTypes() =>
             throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
 
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override FileStream GetFile(string name) =>
             throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
 
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override FileStream[] GetFiles(bool getResourceModules) =>
             throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
 
index 4fe3b9a..fc762fe 100644 (file)
@@ -13,7 +13,11 @@ namespace System.Reflection
         protected Module() { }
 
         public virtual Assembly Assembly => throw NotImplemented.ByDesign;
+
+        internal const string UnknownStringMessageInRAF = "Returns <Unknown> for modules with no file path";
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public virtual string FullyQualifiedName => throw NotImplemented.ByDesign;
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public virtual string Name => throw NotImplemented.ByDesign;
 
         public virtual int MDStreamVersion => throw NotImplemented.ByDesign;
index c1f11fc..0c34b67 100644 (file)
@@ -3,6 +3,7 @@
 
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 
 namespace System.Reflection.Context.Delegation
 {
@@ -22,6 +23,11 @@ namespace System.Reflection.Context.Delegation
             get { return UnderlyingModule.Assembly; }
         }
 
+        internal const string UnknownStringMessageInRAF = "Returns <Unknown> for modules with no file path";
+
+#if NET5_0_OR_GREATER
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
+#endif
         public override string FullyQualifiedName
         {
             get { return UnderlyingModule.FullyQualifiedName; }
@@ -42,6 +48,9 @@ namespace System.Reflection.Context.Delegation
             get { return UnderlyingModule.ModuleVersionId; }
         }
 
+#if NET5_0_OR_GREATER
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
+#endif
         public override string Name
         {
             get { return UnderlyingModule.Name; }
index e823c6a..cbbcaa2 100644 (file)
@@ -29,7 +29,9 @@ namespace System.Reflection.Emit
         public System.Reflection.Emit.ModuleBuilder? GetDynamicModule(string name) { throw null; }
         [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
         public override System.Type[] GetExportedTypes() { throw null; }
+        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("This member throws an exception for assemblies embedded in a single-file app")]
         public override System.IO.FileStream GetFile(string name) { throw null; }
+        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("This member throws an exception for assemblies embedded in a single-file app")]
         public override System.IO.FileStream[] GetFiles(bool getResourceModules) { throw null; }
         public override int GetHashCode() { throw null; }
         public override System.Reflection.Module[] GetLoadedModules(bool getResourceModules) { throw null; }
index 976d002..fea1363 100644 (file)
@@ -1,6 +1,7 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.Reflection.Metadata;
 
@@ -51,6 +52,8 @@ namespace System.Reflection.TypeLoading.Ecma
             return resourceNames;
         }
 
+        [UnconditionalSuppressMessage("SingleFile", "IL3002:RequiresAssemblyFiles on Module.GetFile",
+            Justification = "ResourceLocation should never be ContainedInAnotherAssembly if embedded in a single-file")]
         public sealed override Stream? GetManifestResourceStream(string name)
         {
             if (name == null)
index fe92aa5..d141c71 100644 (file)
@@ -4,6 +4,7 @@
 using System.IO;
 using System.Threading;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Collections.Generic;
 
 namespace System.Reflection.TypeLoading
@@ -16,6 +17,9 @@ namespace System.Reflection.TypeLoading
         public sealed override Module? GetModule(string name) => GetRoModule(name);
         public sealed override Module[] GetModules(bool getResourceModules) => ComputeRoModules(getResourceModules).CloneArray<Module>();
 
+#if NET5_0_OR_GREATER
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
+#endif
         public sealed override FileStream? GetFile(string name)
         {
             Module? m = GetModule(name);
@@ -24,6 +28,9 @@ namespace System.Reflection.TypeLoading
             return new FileStream(m.FullyQualifiedName, FileMode.Open, FileAccess.Read, FileShare.Read);
         }
 
+#if NET5_0_OR_GREATER
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
+#endif
         public sealed override FileStream[] GetFiles(bool getResourceModules)
         {
             Module[] m = GetModules(getResourceModules);
index 114f581..4d48000 100644 (file)
@@ -40,16 +40,18 @@ namespace System.Reflection.TypeLoading
         public sealed override string FullName => _lazyFullName ?? (_lazyFullName = GetName().FullName);
         private volatile string? _lazyFullName;
 
+        internal const string ThrowingMessageInRAF = "This member throws an exception for assemblies embedded in a single-file app";
+
         // Location and codebase
         public abstract override string Location { get; }
 #if NET5_0_OR_GREATER
         [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
-        [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
 #endif
         public sealed override string CodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase);
 #if NET5_0_OR_GREATER
         [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
-        [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
 #endif
         public sealed override string EscapedCodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase);
 
index 78f4d92..cba5234 100644 (file)
@@ -1,6 +1,7 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System.Diagnostics.CodeAnalysis;
 using System.Reflection.Metadata;
 
 namespace System.Reflection.TypeLoading.Ecma
@@ -16,6 +17,8 @@ namespace System.Reflection.TypeLoading.Ecma
         /// If a type is not contained or forwarded from the assembly, this method returns null (does not throw.)
         /// This supports the "throwOnError: false" behavior of Module.GetType(string, bool).
         /// </summary>
+        [UnconditionalSuppressMessage("SingleFile", "IL3002:RequiresAssemblyFiles on FullyQualifiedName",
+            Justification = "FullyQualifiedName is only used for exception message")]
         protected sealed override RoDefinitionType? GetTypeCoreNoCache(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name, out Exception? e)
         {
             MetadataReader reader = Reader;
index e9727f2..4ddd442 100644 (file)
@@ -3,6 +3,7 @@
 
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.Runtime.Serialization;
 
@@ -15,7 +16,7 @@ namespace System.Reflection.TypeLoading
     {
         private readonly string _fullyQualifiedName;
 
-        internal const string FullyQualifiedNameForModulesLoadedFromByteArrays = "<unknown>";
+        internal const string FullyQualifiedNameForModulesLoadedFromByteArrays = "<Unknown>";
 
         internal RoModule(string fullyQualifiedName)
             : base()
@@ -30,11 +31,19 @@ namespace System.Reflection.TypeLoading
         public sealed override Assembly Assembly => GetRoAssembly();
         internal abstract RoAssembly GetRoAssembly();
 
+        internal const string UnknownStringMessageInRAF = "Returns <Unknown> for modules with no file path";
+
+#if NET5_0_OR_GREATER
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
+#endif
         public sealed override string FullyQualifiedName => _fullyQualifiedName;
         public abstract override int MDStreamVersion { get; }
         public abstract override int MetadataToken { get; }
         public abstract override Guid ModuleVersionId { get; }
 
+#if NET5_0_OR_GREATER
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
+#endif
         public sealed override string Name
         {
             get
index 9bff8ab..7e2adb5 100644 (file)
@@ -3,6 +3,7 @@
 
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 
 namespace System.Reflection.TypeLoading
 {
@@ -30,6 +31,9 @@ namespace System.Reflection.TypeLoading
         public sealed override int MDStreamVersion => throw new InvalidOperationException(SR.ResourceOnlyModule);
         public sealed override int MetadataToken => 0x00000000;
         public sealed override Guid ModuleVersionId => throw new InvalidOperationException(SR.ResourceOnlyModule);
+
+        [UnconditionalSuppressMessage("SingleFile", "IL3002:RequiresAssemblyFiles on Name",
+            Justification = "https://github.com/dotnet/runtime/issues/56519")]
         public sealed override string ScopeName => Name;
         public sealed override void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
         {
index 578d04f..569cc33 100644 (file)
@@ -234,8 +234,8 @@ namespace System.Reflection.Tests
                 Assert.Equal(m, m1);
 
                 Assert.Equal(a, m.Assembly);
-                Assert.Equal("<unknown>", m.FullyQualifiedName);
-                Assert.Equal("<unknown>", m.Name);
+                Assert.Equal("<Unknown>", m.FullyQualifiedName);
+                Assert.Equal("<Unknown>", m.Name);
                 Assert.Equal("Joe.netmodule", m.ScopeName);
                 Assert.Equal(TestData.s_JoeNetModuleMvid, m.ModuleVersionId);
             }
index a94b40b..380e0a2 100644 (file)
@@ -11060,13 +11060,13 @@ namespace System.Reflection
     {
         protected Assembly() { }
         [System.ObsoleteAttribute("Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
-        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("The code will throw for assemblies embedded in a single-file app")]
+        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("This member throws an exception for assemblies embedded in a single-file app")]
         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("Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
-        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("The code will throw for assemblies embedded in a single-file app")]
+        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("This member throws an exception for assemblies embedded in a single-file app")]
         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; } }
@@ -11100,9 +11100,11 @@ namespace System.Reflection
         public static System.Reflection.Assembly GetExecutingAssembly() { throw null; }
         [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
         public virtual System.Type[] GetExportedTypes() { throw null; }
+        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("This member throws an exception for assemblies embedded in a single-file app")]
         public virtual System.IO.FileStream? GetFile(string name) { throw null; }
-        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("This member throws an exception for assemblies embedded in a single-file app")]
         public virtual System.IO.FileStream[] GetFiles() { throw null; }
+        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("This member throws an exception for assemblies embedded in a single-file app")]
         public virtual System.IO.FileStream[] GetFiles(bool getResourceModules) { throw null; }
         [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
         public virtual System.Type[] GetForwardedTypes() { throw null; }
@@ -11867,11 +11869,13 @@ namespace System.Reflection
         protected Module() { }
         public virtual System.Reflection.Assembly Assembly { get { throw null; } }
         public virtual System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> CustomAttributes { get { throw null; } }
+        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("Returns <Unknown> for modules with no file path")]
         public virtual string FullyQualifiedName { get { throw null; } }
         public virtual int MDStreamVersion { get { throw null; } }
         public virtual int MetadataToken { get { throw null; } }
         public System.ModuleHandle ModuleHandle { get { throw null; } }
         public virtual System.Guid ModuleVersionId { get { throw null; } }
+        [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("Returns <Unknown> for modules with no file path")]
         public virtual string Name { get { throw null; } }
         public virtual string ScopeName { get { throw null; } }
         public override bool Equals(object? o) { throw null; }
index 86ba437..427767a 100644 (file)
@@ -106,6 +106,7 @@ namespace System.Reflection.Emit
             set_wrappers_type(this, type);
         }
 
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public override string FullyQualifiedName
         {
             get
@@ -816,6 +817,7 @@ namespace System.Reflection.Emit
             get { return assemblyb; }
         }
 
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public override string Name
         {
             get { return name; }
@@ -874,7 +876,7 @@ namespace System.Reflection.Emit
 
             m = GetRegisteredToken(metadataToken) as MemberInfo;
             if (m == null)
-                throw RuntimeModule.resolve_token_exception(Name, metadataToken, error, "MemberInfo");
+                throw RuntimeModule.resolve_token_exception(this, metadataToken, error, "MemberInfo");
             else
                 return m;
         }
index d5fa9e4..95aed37 100644 (file)
@@ -74,7 +74,7 @@ namespace System.Reflection
 
         public override bool ReflectionOnly => false;
 
-        [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override string? CodeBase
         {
             get
@@ -410,6 +410,7 @@ namespace System.Reflection
             return res;
         }
 
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override FileStream? GetFile(string name)
         {
             if (name == null)
@@ -430,6 +431,7 @@ namespace System.Reflection
                 return null;
         }
 
+        [RequiresAssemblyFiles(ThrowingMessageInRAF)]
         public override FileStream[] GetFiles(bool getResourceModules)
         {
             if (Location.Length == 0)
index 692d7ff..9b92b12 100644 (file)
@@ -56,6 +56,7 @@ namespace System.Reflection
             get { return assembly; }
         }
 
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public
         override
         // Note: we do not ask for PathDiscovery because no path is returned here.
@@ -94,6 +95,7 @@ namespace System.Reflection
             }
         }
 
+        [RequiresAssemblyFiles(UnknownStringMessageInRAF)]
         public override
         string FullyQualifiedName
         {
@@ -232,7 +234,7 @@ namespace System.Reflection
 
             IntPtr handle = ResolveFieldToken(monoModule, metadataToken, ptrs_from_types(genericTypeArguments), ptrs_from_types(genericMethodArguments), out error);
             if (handle == IntPtr.Zero)
-                throw resolve_token_exception(module.Name, metadataToken, error, "Field");
+                throw resolve_token_exception(module, metadataToken, error, "Field");
             else
                 return FieldInfo.GetFieldFromHandle(new RuntimeFieldHandle(handle));
         }
@@ -251,7 +253,7 @@ namespace System.Reflection
 
             MemberInfo m = ResolveMemberToken(monoModule, metadataToken, ptrs_from_types(genericTypeArguments), ptrs_from_types(genericMethodArguments), out error);
             if (m == null)
-                throw resolve_token_exception(module.Name, metadataToken, error, "MemberInfo");
+                throw resolve_token_exception(module, metadataToken, error, "MemberInfo");
             else
                 return m;
         }
@@ -270,7 +272,7 @@ namespace System.Reflection
 
             IntPtr handle = ResolveMethodToken(monoModule, metadataToken, ptrs_from_types(genericTypeArguments), ptrs_from_types(genericMethodArguments), out error);
             if (handle == IntPtr.Zero)
-                throw resolve_token_exception(module.Name, metadataToken, error, "MethodBase");
+                throw resolve_token_exception(module, metadataToken, error, "MethodBase");
             else
                 return RuntimeMethodInfo.GetMethodFromHandleNoGenericCheck(new RuntimeMethodHandle(handle));
         }
@@ -289,7 +291,7 @@ namespace System.Reflection
 
             string s = ResolveStringToken(monoModule, metadataToken, out error);
             if (s == null)
-                throw resolve_token_exception(module.Name, metadataToken, error, "string");
+                throw resolve_token_exception(module, metadataToken, error, "string");
             else
                 return s;
         }
@@ -308,7 +310,7 @@ namespace System.Reflection
 
             IntPtr handle = ResolveTypeToken(monoModule, metadataToken, ptrs_from_types(genericTypeArguments), ptrs_from_types(genericMethodArguments), out error);
             if (handle == IntPtr.Zero)
-                throw resolve_token_exception(module.Name, metadataToken, error, "Type");
+                throw resolve_token_exception(module, metadataToken, error, "Type");
             else
                 return Type.GetTypeFromHandle(new RuntimeTypeHandle(handle));
         }
@@ -327,7 +329,7 @@ namespace System.Reflection
 
             byte[] res = ResolveSignature(monoModule, metadataToken, out error);
             if (res == null)
-                throw resolve_token_exception(module.Name, metadataToken, error, "signature");
+                throw resolve_token_exception(module, metadataToken, error, "signature");
             else
                 return res;
         }
@@ -364,6 +366,11 @@ namespace System.Reflection
             return new Guid(guid);
         }
 
+        [UnconditionalSuppressMessage("SingleFile", "IL3002:RequiresAssemblyFiles",
+            Justification = "Module Name is used only for diagnostic reporting message")]
+        internal static Exception resolve_token_exception(Module module, int metadataToken, ResolveTokenError error, string tokenType)
+            => resolve_token_exception(module.Name, metadataToken, error, tokenType);
+
         internal static Exception resolve_token_exception(string name, int metadataToken, ResolveTokenError error, string tokenType)
         {
             if (error == ResolveTokenError.OutOfRange)