Skip to content

Commit

Permalink
Unify Requires Attribute (#55622)
Browse files Browse the repository at this point in the history
Add an overload to RequiresAssemblyFiles to be able to have the same user experience as if using RequiresUnreferencedCode
  • Loading branch information
tlakollo authored Jul 14, 2021
1 parent 95044fd commit bf014b5
Show file tree
Hide file tree
Showing 14 changed files with 46 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public override FileStream[] GetFiles(bool getResourceModules)

public override string Location => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);

[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);

[RequiresUnreferencedCode("Types might be removed")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private static extern bool GetCodeBase(QCallAssembly assembly,
return null;
}

[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
public override string? CodeBase
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ public partial class DependencyContext
public DependencyContext(Microsoft.Extensions.DependencyModel.TargetInfo target, Microsoft.Extensions.DependencyModel.CompilationOptions compilationOptions, System.Collections.Generic.IEnumerable<Microsoft.Extensions.DependencyModel.CompilationLibrary> compileLibraries, System.Collections.Generic.IEnumerable<Microsoft.Extensions.DependencyModel.RuntimeLibrary> runtimeLibraries, System.Collections.Generic.IEnumerable<Microsoft.Extensions.DependencyModel.RuntimeFallbacks> runtimeGraph) { }
public Microsoft.Extensions.DependencyModel.CompilationOptions CompilationOptions { get { throw null; } }
public System.Collections.Generic.IReadOnlyList<Microsoft.Extensions.DependencyModel.CompilationLibrary> CompileLibraries { get { throw null; } }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static Microsoft.Extensions.DependencyModel.DependencyContext Default { get { throw null; } }
public System.Collections.Generic.IReadOnlyList<Microsoft.Extensions.DependencyModel.RuntimeFallbacks> RuntimeGraph { get { throw null; } }
public System.Collections.Generic.IReadOnlyList<Microsoft.Extensions.DependencyModel.RuntimeLibrary> RuntimeLibraries { get { throw null; } }
public Microsoft.Extensions.DependencyModel.TargetInfo Target { get { throw null; } }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static Microsoft.Extensions.DependencyModel.DependencyContext Load(System.Reflection.Assembly assembly) { throw null; }
public Microsoft.Extensions.DependencyModel.DependencyContext Merge(Microsoft.Extensions.DependencyModel.DependencyContext other) { throw null; }
}
Expand Down Expand Up @@ -97,7 +97,7 @@ public partial class DependencyContextLoader
{
public DependencyContextLoader() { }
public static Microsoft.Extensions.DependencyModel.DependencyContextLoader Default { get { throw null; } }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public Microsoft.Extensions.DependencyModel.DependencyContext Load(System.Reflection.Assembly assembly) { throw null; }
}
public partial class DependencyContextWriter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public DependencyContext(TargetInfo target,
RuntimeGraph = runtimeGraph.ToArray();
}

[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
[RequiresAssemblyFiles("DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static DependencyContext Default => _defaultContext.Value;

public TargetInfo Target { get; }
Expand Down Expand Up @@ -79,7 +79,7 @@ public DependencyContext Merge(DependencyContext other)
);
}

[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
[RequiresAssemblyFiles("DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
private static DependencyContext LoadDefault()
{
var entryAssembly = Assembly.GetEntryAssembly();
Expand All @@ -91,7 +91,7 @@ private static DependencyContext LoadDefault()
return Load(entryAssembly);
}

[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
[RequiresAssemblyFiles("DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static DependencyContext Load(Assembly assembly)
{
return DependencyContextLoader.Default.Load(assembly);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private static Stream GetResourceStream(Assembly assembly, string name)
return assembly.GetManifestResourceStream(name);
}

[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
[RequiresAssemblyFiles("DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public DependencyContext Load(Assembly assembly)
{
if (assembly == null)
Expand Down Expand Up @@ -105,7 +105,7 @@ private DependencyContext LoadContext(IDependencyContextReader reader, string lo
return null;
}

[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
[RequiresAssemblyFiles("DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
private DependencyContext LoadAssemblyContext(Assembly assembly, IDependencyContextReader reader)
{
using (Stream stream = GetResourceStream(assembly, assembly.GetName().Name + DepsJsonExtension))
Expand All @@ -128,7 +128,7 @@ private DependencyContext LoadAssemblyContext(Assembly assembly, IDependencyCont
return null;
}

[RequiresAssemblyFiles(Message = "The use of DependencyContextLoader is not supported when publishing as single-file")]
[RequiresAssemblyFiles("The use of DependencyContextLoader is not supported when publishing as single-file")]
private string GetDepsJsonPath(Assembly assembly)
{
// Assemblies loaded in memory (e.g. single file) return empty string from Location.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,22 @@ sealed class RequiresAssemblyFilesAttribute : Attribute
/// </summary>
public RequiresAssemblyFilesAttribute() { }

/// <summary>
/// Initializes a new instance of the <see cref="RequiresAssemblyFilesAttribute"/> class.
/// </summary>
/// <param name="message">
/// A message that contains information about the need for assembly files to be on disk.
/// </param>
public RequiresAssemblyFilesAttribute(string message)
{
Message = message;
}

/// <summary>
/// Gets or sets an optional message that contains information about the need for
/// assembly files to be on disk.
/// </summary>
public string? Message { get; set; }
public string? Message { get; }

/// <summary>
/// Gets or sets an optional URL that contains more information about the member,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public virtual IEnumerable<Type> ExportedTypes
[RequiresUnreferencedCode("Types might be removed")]
public virtual Type[] GetForwardedTypes() { throw NotImplemented.ByDesign; }

[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
public virtual string? CodeBase => throw NotImplemented.ByDesign;
public virtual MethodInfo? EntryPoint => throw NotImplemented.ByDesign;
public virtual string? FullName => throw NotImplemented.ByDesign;
Expand Down Expand Up @@ -116,7 +116,7 @@ public virtual IEnumerable<Type> ExportedTypes
public virtual object[] GetCustomAttributes(bool inherit) { throw NotImplemented.ByDesign; }
public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }

[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
public virtual string EscapedCodeBase => AssemblyName.EscapeCodeBase(CodeBase);

[RequiresUnreferencedCode("Assembly.CreateInstance is not supported with trimming. Use Type.GetType instead.")]
Expand Down Expand Up @@ -154,7 +154,7 @@ public virtual IEnumerable<Type> ExportedTypes
public virtual Assembly GetSatelliteAssembly(CultureInfo culture, Version? version) { throw NotImplemented.ByDesign; }

public virtual FileStream? GetFile(string name) { throw NotImplemented.ByDesign; }
[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
public virtual FileStream[] GetFiles() => GetFiles(getResourceModules: false);
public virtual FileStream[] GetFiles(bool getResourceModules) { throw NotImplemented.ByDesign; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ public string? CultureName

public string? CodeBase
{
[RequiresAssemblyFiles(Message = "The code will return an empty string for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will return an empty string for assemblies embedded in a single-file app")]
get => _codeBase;
set => _codeBase = value;
}

[RequiresAssemblyFiles(Message = "The code will return an empty string for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will return an empty string for assemblies embedded in a single-file app")]
public string? EscapedCodeBase
{
get
Expand Down Expand Up @@ -261,7 +261,7 @@ public static bool ReferenceMatchesDefinition(AssemblyName? reference, AssemblyN
return refName.Equals(defName, StringComparison.OrdinalIgnoreCase);
}

[RequiresAssemblyFiles(Message = "The code will return an empty string for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will return an empty string for assemblies embedded in a single-file app")]
internal static string EscapeCodeBase(string? codebase)
{
if (codebase == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace System.Reflection.Emit
{
public sealed partial class AssemblyBuilder : Assembly
{
[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public DelegatingAssembly(Assembly assembly)
}

#pragma warning disable IL3003 // netstandard2.1 didn't have RequiresAssemblyFiles attributes applied on Assembly
[RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3000")]
[RequiresAssemblyFiles("Calling 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3000")]
public override string Location
{
get { return UnderlyingAssembly.Location; }
Expand Down Expand Up @@ -111,19 +111,19 @@ public override Type[] GetExportedTypes()
}

#pragma warning disable IL3003 // netstandard2.1 didn't have RequiresAssemblyFiles attributes applied on Assembly
[RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.GetFile(string)' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
[RequiresAssemblyFiles("Calling 'System.Reflection.Assembly.GetFile(string)' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
public override FileStream? GetFile(string name)
{
return UnderlyingAssembly.GetFile(name);
}

[RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
[RequiresAssemblyFiles("Calling 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
public override FileStream[] GetFiles()
{
return UnderlyingAssembly.GetFiles();
}

[RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.GetFiles(bool)' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
[RequiresAssemblyFiles("Calling 'System.Reflection.Assembly.GetFiles(bool)' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
public override FileStream[] GetFiles(bool getResourceModules)
{
return UnderlyingAssembly.GetFiles(getResourceModules);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ protected RoAssembly(MetadataLoadContext loader, int assemblyFileCount)
public abstract override string Location { get; }
#if NET5_0_OR_GREATER
[Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
#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(Message = "The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
#endif
public sealed override string EscapedCodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase);

Expand Down
Loading

0 comments on commit bf014b5

Please sign in to comment.