From a8180948d23e00571b1b2c6bbfffba002178c630 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Thu, 14 Jul 2022 16:29:23 -0700 Subject: [PATCH 1/5] Add support for `required` keyword to GenAPI Also avoid emitting the new `CompilerFeatureRequiredAttribute` --- .../Extensions/CSharp/CSharpCciExtensions.cs | 5 +++++ .../Writers/CSharp/CSDeclarationWriter.Attributes.cs | 11 +++++++---- .../Writers/CSharp/CSDeclarationWriter.Fields.cs | 5 +++++ .../Writers/CSharp/CSDeclarationWriter.Properties.cs | 5 +++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Cci.Extensions/Extensions/CSharp/CSharpCciExtensions.cs b/src/Microsoft.Cci.Extensions/Extensions/CSharp/CSharpCciExtensions.cs index 44461e0f7c7..dd2d6f569b4 100644 --- a/src/Microsoft.Cci.Extensions/Extensions/CSharp/CSharpCciExtensions.cs +++ b/src/Microsoft.Cci.Extensions/Extensions/CSharp/CSharpCciExtensions.cs @@ -805,6 +805,11 @@ public static bool HasNativeIntegerAttribute(this IEnumerable return attributes.HasAttributeOfType("System.Runtime.CompilerServices.NativeIntegerAttribute"); } + public static bool HasRequiredMemberAttribute(this IEnumerable attributes) + { + return attributes.HasAttributeOfType("System.Runtime.CompilerServices.RequiredMemberAttribute"); + } + public static string[] GetValueTupleNames(this IEnumerable attributes) { string[] names = null; diff --git a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs index b2f74d5edb0..150317a210a 100644 --- a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs +++ b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs @@ -376,15 +376,18 @@ private static bool ExcludeSpecialAttribute(ICustomAttribute c) switch (typeName) { - case "System.Runtime.CompilerServices.FixedBufferAttribute": return true; + case "System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute": return true; case "System.ParamArrayAttribute": return true; - case "System.Reflection.DefaultMemberAttribute": return true; - case "System.Reflection.AssemblyKeyFileAttribute": return true; case "System.Reflection.AssemblyDelaySignAttribute": return true; - case "System.Runtime.CompilerServices.ExtensionAttribute": return true; + case "System.Reflection.AssemblyKeyFileAttribute": return true; + case "System.Reflection.DefaultMemberAttribute": return true; + case "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute": return true; case "System.Runtime.CompilerServices.DynamicAttribute": return true; + case "System.Runtime.CompilerServices.ExtensionAttribute": return true; + case "System.Runtime.CompilerServices.FixedBufferAttribute": return true; case "System.Runtime.CompilerServices.IsByRefLikeAttribute": return true; case "System.Runtime.CompilerServices.IsReadOnlyAttribute": return true; + case "System.Runtime.CompilerServices.RequiredMemberAttribute": return true; case "System.Runtime.CompilerServices.TupleElementNamesAttribute": return true; case "System.ObsoleteAttribute": { diff --git a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Fields.cs b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Fields.cs index 75982496847..4ea94ddb448 100644 --- a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Fields.cs +++ b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Fields.cs @@ -30,6 +30,11 @@ private void WriteFieldDefinition(IFieldDefinition field) WriteVisibility(field.Visibility); WriteCustomModifiers(field.CustomModifiers); + if (field.Attributes.HasRequiredMemberAttribute()) + { + WriteKeyword("required"); + } + if (field.Type.IsUnsafeType()) WriteKeyword("unsafe"); diff --git a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Properties.cs b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Properties.cs index c68e02ba585..8a718222569 100644 --- a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Properties.cs +++ b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Properties.cs @@ -74,6 +74,11 @@ private void WritePropertyDefinition(IPropertyDefinition property) WriteVisibility(property.Visibility); } + if (property.Attributes.HasRequiredMemberAttribute()) + { + WriteKeyword("required"); + } + // Getter and Setter modifiers should be the same WriteMethodModifiers(accessor); From 9467cd4ce274a8bf043934755402fd85a3fbaf1c Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Thu, 14 Jul 2022 16:30:57 -0700 Subject: [PATCH 2/5] Support LangVersion in Roslyn-based GenFacades tasks --- .../GenPartialFacadeSource.cs | 3 +++ .../GenPartialFacadeSourceGenerator.cs | 3 ++- .../NotSupportedAssemblyGenerator.cs | 9 ++++++++- .../SourceGenerator.cs | 3 ++- src/Microsoft.DotNet.GenFacades/TypeParser.cs | 16 ++++++++++++---- ...crosoft.DotNet.GenFacadesNotSupported.targets | 1 + ...crosoft.DotNet.GenPartialFacadeSource.targets | 1 + 7 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSource.cs b/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSource.cs index c0083a78409..da5e880ece8 100644 --- a/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSource.cs +++ b/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSource.cs @@ -21,6 +21,8 @@ public class GenPartialFacadeSource : BuildTask public string DefineConstants { get; set; } + public string LangVersion { get; set; } + public bool IgnoreMissingTypes { get; set; } public string[] IgnoreMissingTypesList { get; set; } @@ -42,6 +44,7 @@ public override bool Execute() ReferenceAssembly, CompileFiles?.Select(item => item.ItemSpec).ToArray(), DefineConstants, + LangVersion, OutputSourcePath, Log, IgnoreMissingTypes, diff --git a/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSourceGenerator.cs b/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSourceGenerator.cs index 0eeb1803204..1ec90b35153 100644 --- a/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSourceGenerator.cs +++ b/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSourceGenerator.cs @@ -21,6 +21,7 @@ public static bool Execute( string contractAssembly, string[] compileFiles, string defineConstants, + string langVersion, string outputSourcePath, ILog logger, bool ignoreMissingTypes = false, @@ -52,7 +53,7 @@ public static bool Execute( referenceTypes = referenceTypes.Where(type => !OmitTypes.Contains(type)); var sourceGenerator = new SourceGenerator(referenceTypes, seedTypes, seedTypePreferences, outputSourcePath, ignoreMissingTypesList, logger); - return sourceGenerator.GenerateSource(compileFiles, ParseDefineConstants(defineConstants), ignoreMissingTypes); + return sourceGenerator.GenerateSource(compileFiles, ParseDefineConstants(defineConstants), langVersion, ignoreMissingTypes); } private static IEnumerable ParseDefineConstants(string defineConstants) diff --git a/src/Microsoft.DotNet.GenFacades/NotSupportedAssemblyGenerator.cs b/src/Microsoft.DotNet.GenFacades/NotSupportedAssemblyGenerator.cs index 235f10e4c5c..60141a530a1 100644 --- a/src/Microsoft.DotNet.GenFacades/NotSupportedAssemblyGenerator.cs +++ b/src/Microsoft.DotNet.GenFacades/NotSupportedAssemblyGenerator.cs @@ -24,6 +24,7 @@ public class NotSupportedAssemblyGenerator : BuildTask [Required] public string Message { get; set; } + public string LangVersion { get; set; } public string ApiExclusionListPath { get; set; } public override bool Execute() @@ -68,7 +69,13 @@ private void GenerateNotSupportedAssemblyForSourceFile(string sourceFile, string try { - syntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText(sourceFile)); + LanguageVersion languageVersion = LanguageVersion.Default; + if (!String.IsNullOrEmpty(LangVersion) && !LanguageVersionFacts.TryParse(LangVersion, out languageVersion)) + { + Log.LogError($"Invalid LangVersion value '{LangVersion}'"); + return; + } + syntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText(sourceFile), new CSharpParseOptions(languageVersion)); } catch(Exception ex) { diff --git a/src/Microsoft.DotNet.GenFacades/SourceGenerator.cs b/src/Microsoft.DotNet.GenFacades/SourceGenerator.cs index b34212138a4..d42f64b96fc 100644 --- a/src/Microsoft.DotNet.GenFacades/SourceGenerator.cs +++ b/src/Microsoft.DotNet.GenFacades/SourceGenerator.cs @@ -41,6 +41,7 @@ ILog logger public bool GenerateSource( IEnumerable compileFiles, IEnumerable constants, + string langVersion, bool ignoreMissingTypes) { List externAliases = new List(); @@ -51,7 +52,7 @@ public bool GenerateSource( bool result = true; - HashSet existingTypes = compileFiles != null ? TypeParser.GetAllPublicTypes(compileFiles, constants) : null; + HashSet existingTypes = compileFiles != null ? TypeParser.GetAllPublicTypes(compileFiles, constants, langVersion) : null; IEnumerable typesToForward = compileFiles == null ? _referenceTypes : _referenceTypes.Where(id => !existingTypes.Contains(id)); foreach (string type in typesToForward.OrderBy(s => s)) diff --git a/src/Microsoft.DotNet.GenFacades/TypeParser.cs b/src/Microsoft.DotNet.GenFacades/TypeParser.cs index 5dedf9ee4f9..c6bd6426f24 100644 --- a/src/Microsoft.DotNet.GenFacades/TypeParser.cs +++ b/src/Microsoft.DotNet.GenFacades/TypeParser.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -12,10 +13,17 @@ namespace Microsoft.DotNet.GenFacades { internal class TypeParser { - public static HashSet GetAllPublicTypes(IEnumerable files, IEnumerable constants) + public static HashSet GetAllPublicTypes(IEnumerable files, IEnumerable constants, string langVersion) { HashSet types = new HashSet(); - var syntaxTreeCollection = GetSourceTrees(files, constants); + + LanguageVersion languageVersion = LanguageVersion.Default; + if (!string.IsNullOrEmpty(langVersion) && !LanguageVersionFacts.TryParse(langVersion, out languageVersion)) + { + throw new ArgumentException($"Invalid C# language version value '{langVersion}'", nameof(langVersion)); + } + + var syntaxTreeCollection = GetSourceTrees(files, constants, languageVersion); foreach (var tree in syntaxTreeCollection) { @@ -122,9 +130,9 @@ private static string GetNamespaceName(NamespaceDeclarationSyntax namespaceSynta return namespaceSyntax.Name.ToFullString().Trim(); } - private static IEnumerable GetSourceTrees(IEnumerable sourceFiles, IEnumerable constants) + private static IEnumerable GetSourceTrees(IEnumerable sourceFiles, IEnumerable constants, LanguageVersion languageVersion) { - CSharpParseOptions options = new CSharpParseOptions().WithPreprocessorSymbols(constants); + CSharpParseOptions options = new CSharpParseOptions(languageVersion: languageVersion, preprocessorSymbols: constants); List result = new List(); foreach (string sourceFile in sourceFiles) { diff --git a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacadesNotSupported.targets b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacadesNotSupported.targets index d1cce80e65f..7b8469776d5 100644 --- a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacadesNotSupported.targets +++ b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacadesNotSupported.targets @@ -55,6 +55,7 @@ diff --git a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenPartialFacadeSource.targets b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenPartialFacadeSource.targets index 615efc86143..5f9b8bdcc8e 100644 --- a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenPartialFacadeSource.targets +++ b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenPartialFacadeSource.targets @@ -30,6 +30,7 @@ ReferenceAssembly="$(ReferenceAssembly)" CompileFiles="@(Compile)" DefineConstants="$(DefineConstants)" + LangVersion="$(LangVersion)" IgnoreMissingTypes="$(GenFacadesIgnoreMissingTypes)" IgnoreMissingTypesList="@(GenFacadesIgnoreMissingType)" OmitTypes="@(GenFacadesOmitType)" From f163617b99c0fcb13b10209bb7037959c48f2535 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Thu, 14 Jul 2022 16:32:21 -0700 Subject: [PATCH 3/5] Don't redistribute roslyn in GenFacades Use the one that the project is compiling with. This is a copy of the logic from https://github.com/dotnet/sdk/blob/d670c1d9c72190cdf8228ed000847f9bde55ce71/src/Compatibility/Microsoft.DotNet.Compatibility/ValidatePackage.cs#L47 --- .../GenPartialFacadeSource.cs | 4 +- .../Microsoft.DotNet.GenFacades.csproj | 2 +- .../NotSupportedAssemblyGenerator.cs | 5 +- .../RoslynBuildTask.cs | 82 +++++++++++++++++++ .../build/Microsoft.DotNet.GenFacades.targets | 11 +++ ...soft.DotNet.GenFacadesNotSupported.targets | 5 +- ...soft.DotNet.GenPartialFacadeSource.targets | 5 +- 7 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 src/Microsoft.DotNet.GenFacades/RoslynBuildTask.cs diff --git a/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSource.cs b/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSource.cs index da5e880ece8..a4b613890bb 100644 --- a/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSource.cs +++ b/src/Microsoft.DotNet.GenFacades/GenPartialFacadeSource.cs @@ -9,7 +9,7 @@ namespace Microsoft.DotNet.GenFacades { - public class GenPartialFacadeSource : BuildTask + public class GenPartialFacadeSource : RoslynBuildTask { [Required] public ITaskItem[] ReferencePaths { get; set; } @@ -34,7 +34,7 @@ public class GenPartialFacadeSource : BuildTask [Required] public string OutputSourcePath { get; set; } - public override bool Execute() + public override bool ExecuteCore() { bool result = true; try diff --git a/src/Microsoft.DotNet.GenFacades/Microsoft.DotNet.GenFacades.csproj b/src/Microsoft.DotNet.GenFacades/Microsoft.DotNet.GenFacades.csproj index db51ae171ed..d73f6abd254 100644 --- a/src/Microsoft.DotNet.GenFacades/Microsoft.DotNet.GenFacades.csproj +++ b/src/Microsoft.DotNet.GenFacades/Microsoft.DotNet.GenFacades.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/Microsoft.DotNet.GenFacades/NotSupportedAssemblyGenerator.cs b/src/Microsoft.DotNet.GenFacades/NotSupportedAssemblyGenerator.cs index 60141a530a1..467858088e8 100644 --- a/src/Microsoft.DotNet.GenFacades/NotSupportedAssemblyGenerator.cs +++ b/src/Microsoft.DotNet.GenFacades/NotSupportedAssemblyGenerator.cs @@ -16,7 +16,7 @@ namespace Microsoft.DotNet.GenFacades /// /// The class generates an NotSupportedAssembly from the reference sources. /// - public class NotSupportedAssemblyGenerator : BuildTask + public class NotSupportedAssemblyGenerator : RoslynBuildTask { [Required] public ITaskItem[] SourceFiles { get; set; } @@ -25,9 +25,10 @@ public class NotSupportedAssemblyGenerator : BuildTask public string Message { get; set; } public string LangVersion { get; set; } + public string ApiExclusionListPath { get; set; } - public override bool Execute() + public override bool ExecuteCore() { if (SourceFiles == null || SourceFiles.Length == 0) { diff --git a/src/Microsoft.DotNet.GenFacades/RoslynBuildTask.cs b/src/Microsoft.DotNet.GenFacades/RoslynBuildTask.cs new file mode 100644 index 00000000000..42b61be4397 --- /dev/null +++ b/src/Microsoft.DotNet.GenFacades/RoslynBuildTask.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using System; +using System.IO; +using System.Reflection; +#if NETCOREAPP +using System.Runtime.Loader; +#endif + +namespace Microsoft.DotNet.Build.Tasks +{ + public abstract partial class RoslynBuildTask : BuildTask + { + [Required] + public string RoslynAssembliesPath { get; set; } + + public override bool Execute() + { +#if NETCOREAPP + AssemblyLoadContext currentContext = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly())!; + currentContext.Resolving += ResolverForRoslyn; +#else + AppDomain.CurrentDomain.AssemblyResolve += ResolverForRoslyn; +#endif + try + { + return ExecuteCore(); + } + finally + { +#if NETCOREAPP + currentContext.Resolving -= ResolverForRoslyn; +#else + AppDomain.CurrentDomain.AssemblyResolve -= ResolverForRoslyn; +#endif + } + } + + public abstract bool ExecuteCore(); + +#if NETCOREAPP + private Assembly ResolverForRoslyn(AssemblyLoadContext context, AssemblyName assemblyName) + { + return LoadRoslyn(assemblyName, path => context.LoadFromAssemblyPath(path)); + } +#else + private Assembly ResolverForRoslyn(object sender, ResolveEventArgs args) + { + AssemblyName name = new(args.Name); + return LoadRoslyn(name, path => Assembly.LoadFrom(path)); + } +#endif + + private Assembly LoadRoslyn(AssemblyName name, Func loadFromPath) + { + const string codeAnalysisName = "Microsoft.CodeAnalysis"; + const string codeAnalysisCsharpName = "Microsoft.CodeAnalysis.CSharp"; + if (name.Name == codeAnalysisName || name.Name == codeAnalysisCsharpName) + { + Assembly asm = loadFromPath(Path.Combine(RoslynAssembliesPath!, $"{name.Name}.dll")); + Version resolvedVersion = asm.GetName().Version; + if (resolvedVersion < name.Version) + { + throw new Exception($"The minimum version required of Roslyn is '{name.Version}' and you are using '{resolvedVersion}' version of the Roslyn. You can update the sdk to get the latest version."); + } + + // Being extra defensive but we want to avoid that we accidentally load two different versions of either + // of the roslyn assemblies from a different location, so let's load them both on the first request. + Assembly _ = name.Name == codeAnalysisName ? + loadFromPath(Path.Combine(RoslynAssembliesPath!, $"{codeAnalysisCsharpName}.dll")) : + loadFromPath(Path.Combine(RoslynAssembliesPath!, $"{codeAnalysisName}.dll")); + + return asm; + } + + return null; + } + } +} diff --git a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacades.targets b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacades.targets index 482f1c6facc..233c7f28b43 100644 --- a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacades.targets +++ b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacades.targets @@ -6,6 +6,17 @@ $(MSBuildThisFileDirectory)..\tools\net472\Microsoft.DotNet.GenFacades.dll + + + $(RoslynTargetsPath) + <_packageReferenceList>@(PackageReference) + + $([System.IO.Path]::GetDirectoryName($(CSharpCoreTargetsPath))) + $([System.IO.Path]::Combine('$(RoslynAssembliesPath)', bincore)) + + + diff --git a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacadesNotSupported.targets b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacadesNotSupported.targets index 7b8469776d5..2de7a52184d 100644 --- a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacadesNotSupported.targets +++ b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenFacadesNotSupported.targets @@ -47,7 +47,7 @@ + ApiExclusionListPath="$(ApiExclusionListPath)" + RoslynAssembliesPath="$(RoslynAssembliesPath)" /> diff --git a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenPartialFacadeSource.targets b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenPartialFacadeSource.targets index 5f9b8bdcc8e..e595644f69b 100644 --- a/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenPartialFacadeSource.targets +++ b/src/Microsoft.DotNet.GenFacades/build/Microsoft.DotNet.GenPartialFacadeSource.targets @@ -8,7 +8,7 @@ ReferencePath true - $(GeneratePartialFacadeSourceDependsOn);ResolveMatchingContract + $(GeneratePartialFacadeSourceDependsOn);ResolveMatchingContract;_GetRoslynAssembliesPath $(CoreCompileDependsOn);GeneratePartialFacadeSource @@ -35,7 +35,8 @@ IgnoreMissingTypesList="@(GenFacadesIgnoreMissingType)" OmitTypes="@(GenFacadesOmitType)" OutputSourcePath="$(OutputSourcePath)" - SeedTypePreferences="@(SeedTypePreference)" /> + SeedTypePreferences="@(SeedTypePreference)" + RoslynAssembliesPath="$(RoslynAssembliesPath)" /> From 8052e5b16dbbbfda819fcd40326e102b08217c28 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Thu, 14 Jul 2022 16:49:59 -0700 Subject: [PATCH 4/5] Exclude the compiler generated Obsolete attribute from types using `required` --- .../Writers/CSharp/CSDeclarationWriter.Attributes.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs index 150317a210a..8751a5dc5dd 100644 --- a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs +++ b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs @@ -396,7 +396,8 @@ private static bool ExcludeSpecialAttribute(ICustomAttribute c) if (arg?.Value is string) { string argValue = (string)arg.Value; - if (argValue == "Types with embedded references are not supported in this version of your compiler.") + if (argValue == "Types with embedded references are not supported in this version of your compiler." || + argValue == "Constructors of types with required members are not supported in this version of your compiler.") { return true; } From 3858541354749afac8006bd0a4a8af37ee8519cc Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Thu, 14 Jul 2022 16:58:27 -0700 Subject: [PATCH 5/5] Address feedback --- .../Writers/CSharp/CSDeclarationWriter.Attributes.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs index 8751a5dc5dd..c5a04ccb0ad 100644 --- a/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs +++ b/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Attributes.cs @@ -376,7 +376,6 @@ private static bool ExcludeSpecialAttribute(ICustomAttribute c) switch (typeName) { - case "System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute": return true; case "System.ParamArrayAttribute": return true; case "System.Reflection.AssemblyDelaySignAttribute": return true; case "System.Reflection.AssemblyKeyFileAttribute": return true; @@ -396,8 +395,8 @@ private static bool ExcludeSpecialAttribute(ICustomAttribute c) if (arg?.Value is string) { string argValue = (string)arg.Value; - if (argValue == "Types with embedded references are not supported in this version of your compiler." || - argValue == "Constructors of types with required members are not supported in this version of your compiler.") + if (argValue is "Types with embedded references are not supported in this version of your compiler." + or "Constructors of types with required members are not supported in this version of your compiler.") { return true; }