Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set 'TreatWarningsAsErrors' almost everywhere #1592

Merged
merged 11 commits into from
Apr 30, 2024
1 change: 1 addition & 0 deletions src/Authoring/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DisableRuntimeMarshalling>True</DisableRuntimeMarshalling>
</PropertyGroup>

Expand Down
4 changes: 2 additions & 2 deletions src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ private bool IsMethodImpl(IMethodSymbol m, IMethodSymbol interfaceMethod)
}

// the return type can be covariant with the interface method's return type (i.e. a sub-type)
if (SymEq(m.ReturnType, interfaceMethod.ReturnType) && !m.ReturnType.AllInterfaces.Contains(interfaceMethod.ReturnType))
if (SymEq(m.ReturnType, interfaceMethod.ReturnType) && !m.ReturnType.AllInterfaces.Contains(interfaceMethod.ReturnType, SymbolEqualityComparer.Default))
{
return false;
}
Expand All @@ -214,7 +214,7 @@ string QualifiedName(INamedTypeSymbol sym)
return sym.OriginalDefinition.ContainingNamespace + "." + sym.OriginalDefinition.MetadataName;
}

HashSet<ISymbol> classMethods = new();
HashSet<ISymbol> classMethods = new(SymbolEqualityComparer.Default);

foreach (var @interface in typeSymbol.AllInterfaces.
Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)) ||
Expand Down
4 changes: 4 additions & 0 deletions src/Authoring/WinRT.SourceGenerator/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
Expand All @@ -27,6 +28,7 @@ public ComponentGenerator(GeneratorExecutionContext context)
Logger = new Logger(context);
}

[SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1035", Justification = "We need to do file IO to invoke the 'cswinrt' tool.")]
private string GetTempFolder(bool clearSourceFilesFromFolder = false)
{
if (string.IsNullOrEmpty(tempFolder) || !File.Exists(tempFolder))
Expand All @@ -49,6 +51,7 @@ private string GetTempFolder(bool clearSourceFilesFromFolder = false)
return tempFolder;
}

[SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1035", Justification = "We need to do file IO to invoke the 'cswinrt' tool.")]
private void GenerateSources()
{
string cswinrtExe = context.GetCsWinRTExe();
Expand Down Expand Up @@ -134,6 +137,7 @@ private bool CatchWinRTDiagnostics()
return winrtScanner.Found();
}

[SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1035", Justification = "This method is only setting the exit code, not doing actual file IO.")]
public void Generate()
{
if (CatchWinRTDiagnostics())
Expand Down
2 changes: 2 additions & 0 deletions src/Authoring/WinRT.SourceGenerator/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -68,6 +69,7 @@ public static string GetAssemblyVersion(this GeneratorExecutionContext context)
return assemblyVersion;
}

[SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1035", Justification = "We need to do file IO to invoke the 'cswinrt' tool.")]
public static string GetGeneratedFilesDir(this GeneratorExecutionContext context)
{
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGeneratedFilesDir", out var generatedFilesDir);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
using System.Linq;
using System.Runtime.CompilerServices;

#nullable enable

namespace WinRT.SourceGenerator
{

Expand Down
2 changes: 2 additions & 0 deletions src/Authoring/WinRT.SourceGenerator/Logger.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Microsoft.CodeAnalysis;
using System.Diagnostics.CodeAnalysis;
using System.IO;

namespace Generator
{
class Logger
{
[SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1035", Justification = "We need to do file IO to save the 'cswinrt' log file.")]
public Logger(GeneratorExecutionContext context)
{
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTEnableLogging", out var enableLoggingStr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<Copyright>Copyright (c) Microsoft Corporation. All rights reserved.</Copyright>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(SolutionDir)WinRT.Runtime\key.snk</AssemblyOriginatorKeyFile>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
</PropertyGroup>

<ItemGroup>
Expand Down
28 changes: 14 additions & 14 deletions src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,17 @@ class TypeDeclaration
public bool IsSynthesizedInterface;
public bool IsComponentType;

public Dictionary<ISymbol, List<MethodDefinitionHandle>> MethodDefinitions = new Dictionary<ISymbol, List<MethodDefinitionHandle>>();
public Dictionary<ISymbol, List<EntityHandle>> MethodReferences = new Dictionary<ISymbol, List<EntityHandle>>();
public Dictionary<ISymbol, FieldDefinitionHandle> FieldDefinitions = new Dictionary<ISymbol, FieldDefinitionHandle>();
public Dictionary<ISymbol, PropertyDefinitionHandle> PropertyDefinitions = new Dictionary<ISymbol, PropertyDefinitionHandle>();
public Dictionary<ISymbol, EventDefinitionHandle> EventDefinitions = new Dictionary<ISymbol, EventDefinitionHandle>();
public Dictionary<ISymbol, InterfaceImplementationHandle> InterfaceImplDefinitions = new Dictionary<ISymbol, InterfaceImplementationHandle>();
public Dictionary<ISymbol, List<MethodDefinitionHandle>> MethodDefinitions = new(SymbolEqualityComparer.Default);
public Dictionary<ISymbol, List<EntityHandle>> MethodReferences = new(SymbolEqualityComparer.Default);
public Dictionary<ISymbol, FieldDefinitionHandle> FieldDefinitions = new(SymbolEqualityComparer.Default);
public Dictionary<ISymbol, PropertyDefinitionHandle> PropertyDefinitions = new(SymbolEqualityComparer.Default);
public Dictionary<ISymbol, EventDefinitionHandle> EventDefinitions = new(SymbolEqualityComparer.Default);
public Dictionary<ISymbol, InterfaceImplementationHandle> InterfaceImplDefinitions = new(SymbolEqualityComparer.Default);
public Dictionary<string, List<ISymbol>> MethodsByName = new Dictionary<string, List<ISymbol>>(StringComparer.Ordinal);
public Dictionary<ISymbol, string> OverloadedMethods = new Dictionary<ISymbol, string>();
public List<ISymbol> CustomMappedSymbols = new List<ISymbol>();
public HashSet<ISymbol> SymbolsWithAttributes = new HashSet<ISymbol>();
public Dictionary<ISymbol, ISymbol> ClassInterfaceMemberMapping = new Dictionary<ISymbol, ISymbol>();
public Dictionary<ISymbol, string> OverloadedMethods = new(SymbolEqualityComparer.Default);
public List<ISymbol> CustomMappedSymbols = new();
public HashSet<ISymbol> SymbolsWithAttributes = new(SymbolEqualityComparer.Default);
public Dictionary<ISymbol, ISymbol> ClassInterfaceMemberMapping = new(SymbolEqualityComparer.Default);

public TypeDeclaration()
: this(null)
Expand Down Expand Up @@ -799,7 +799,7 @@ private TypeDefinitionHandle AddTypeDefinition(
private void ProcessCustomMappedInterfaces(INamedTypeSymbol classSymbol)
{
Logger.Log("writing custom mapped interfaces for " + QualifiedName(classSymbol));
Dictionary<INamedTypeSymbol, bool> isPublicImplementation = new Dictionary<INamedTypeSymbol, bool>();
Dictionary<INamedTypeSymbol, bool> isPublicImplementation = new(SymbolEqualityComparer.Default);

// Mark custom mapped interface members for removal later.
// Note we want to also mark members from interfaces without mappings.
Expand Down Expand Up @@ -1204,7 +1204,7 @@ Symbol GetType(string type, bool isGeneric = false, int genericIndex = -1, bool

private IEnumerable<INamedTypeSymbol> GetInterfaces(INamedTypeSymbol symbol, bool includeInterfacesWithoutMappings = false)
{
HashSet<INamedTypeSymbol> interfaces = new();
HashSet<INamedTypeSymbol> interfaces = new(SymbolEqualityComparer.Default);

// Gather all interfaces that are publicly accessible. We specifically need to exclude interfaces
// that are not public, as eg. those might be used for additional cloaked WinRT/COM interfaces.
Expand Down Expand Up @@ -1638,7 +1638,7 @@ private void AddCustomAttributes(
constructor.Parameters.Length == primitiveValues.Count &&
constructor.Parameters.Select(param => (param.Type is IErrorTypeSymbol) ?
Model.Compilation.GetTypeByMetadataName(param.Type.ToDisplayString()) : param.Type)
.SequenceEqual(primitiveTypes));
.SequenceEqual(primitiveTypes, SymbolEqualityComparer.Default));

Logger.Log("# matching constructor found: " + matchingConstructor.Count());
Logger.Log("matching constructor found: " + matchingConstructor.First());
Expand Down Expand Up @@ -2257,7 +2257,7 @@ string GetSynthesizedInterfaceName(string className, SynthesizedInterfaceType ty

void AddSynthesizedInterfaces(TypeDeclaration classDeclaration)
{
HashSet<ISymbol> classMembersFromInterfaces = new HashSet<ISymbol>();
HashSet<ISymbol> classMembersFromInterfaces = new(SymbolEqualityComparer.Default);
INamedTypeSymbol classSymbol = classDeclaration.Node as INamedTypeSymbol;
foreach (var @interface in classSymbol.AllInterfaces)
{
Expand Down
1 change: 1 addition & 0 deletions src/Authoring/cswinmd/CsWinMD.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<TargetFrameworks>net6.0</TargetFrameworks>
<RollForward>Major</RollForward>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<Authors>Microsoft Corporation</Authors>
<Company>Microsoft Corporation</Company>
<Product>C#/WinRT</Product>
Expand Down
32 changes: 23 additions & 9 deletions src/Authoring/cswinmd/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ namespace Generator
class ConfigOptions : AnalyzerConfigOptions
{
public Dictionary<string, string> Values { get; set; } = new();
public override bool TryGetValue(string key, [NotNullWhen(true)] out string value)

public override bool TryGetValue(string key, [NotNullWhen(true)] out string? value)
{
return Values.TryGetValue(key, out value);
}
}

class ConfigProvider : AnalyzerConfigOptionsProvider
{
public override AnalyzerConfigOptions GlobalOptions { get; } = new ConfigOptions();
Expand All @@ -34,17 +36,18 @@ public override AnalyzerConfigOptions GetOptions(AdditionalText textFile)
return GlobalOptions;
}
}

class Program
{
#nullable enable
public static void Main(string[] args)
{
var i = new List<string>();
string? o = null;
string? sdkVersion = null;
bool? verbose = false;
bool? nologo = false;
string a = null;
string? a = null;

for (int idx = 0; idx < args.Length; idx++)
{
if (args[idx] == "-i")
Expand Down Expand Up @@ -79,6 +82,7 @@ public static void Main(string[] args)

DoMain(i.ToArray(), o!, a!, sdkVersion, verbose, nologo);
}

/// <summary>
/// CSWinMD - Compile C# definitions to WinMD
/// </summary>
Expand All @@ -95,14 +99,18 @@ public static void DoMain(string[] i, string o, string a, string? sdkVersion, bo
{
Console.WriteLine($"CSWinMD {Assembly.GetExecutingAssembly().GetName().Version}");
}

var outFolder = string.IsNullOrEmpty(o) ? Environment.GetEnvironmentVariable("TEMP")! : o!;

try
{
if (i.Length == 0)
{
Console.Error.WriteLine("No C# source files specified");

return;
} else if (i.Length > 1)
}
else if (i.Length > 1)
{
throw new NotImplementedException("Compiling more than one file is not yet implemented");
}
Expand Down Expand Up @@ -151,8 +159,8 @@ public static void DoMain(string[] i, string o, string a, string? sdkVersion, bo
);

var d = driver.RunGenerators(compilation);

var res = d.GetRunResult();

if (!res.Diagnostics.IsEmpty)
{
Console.WriteLine();
Expand All @@ -162,7 +170,8 @@ public static void DoMain(string[] i, string o, string a, string? sdkVersion, bo
Console.WriteLine($"\t\tIn {v.Location.GetLineSpan()}");
}
Console.WriteLine();
} else
}
else
{
Console.WriteLine($" => {outFolder}\\{componentName}.winmd");
}
Expand All @@ -171,14 +180,18 @@ public static void DoMain(string[] i, string o, string a, string? sdkVersion, bo
{
Console.WriteLine();
Console.Error.WriteLine(e);

if (verbose.HasValue && verbose.Value)
{
var log_txt = Path.Join(outFolder, "log.txt");

try
{
Console.Error.WriteLine(File.ReadAllText(log_txt));
}
catch { }
catch
{
}
}
}
}
Expand All @@ -196,17 +209,18 @@ private static string GetWindowsWinMdPath(string? sdkVersion)
using var roots = hklm.OpenSubKey(@"SOFTWARE\Microsoft\Windows Kits\Installed Roots");
var kitsRoot10 = (string)roots!.GetValue("KitsRoot10")!;
var unionMetadata = Path.Combine(kitsRoot10, "UnionMetadata");

if (sdkVersion == null)
{
var dirs = Directory.EnumerateDirectories(unionMetadata);
var versions = dirs.Where(IsVersion).ToList();
versions.Sort();
sdkVersion = Path.GetFileName(versions.Last());
}

var path = Path.Combine(kitsRoot10, "UnionMetadata", sdkVersion, "Windows.winmd");

return path;
}

#nullable restore
}
}
16 changes: 16 additions & 0 deletions src/Projections/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

<PropertyGroup>
<SimulateCsWinRTNugetReference>true</SimulateCsWinRTNugetReference>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

<!--
Don't fail builds for well known warnings in projections that are lower priority:

"CS0108: 'PivotItemDataAutomationPeer.Realize()' hides inherited member 'ItemAutomationPeer.Realize()'. Use the new keyword if hiding was intended."
"CS0109: The member 'IChatMessage2.Status' does not hide an accessible member. The new keyword is not required."
"CS0114: 'IUnSealedCustomEquals.GetHashCode()' hides inherited member 'object.GetHashCode()'. To make the current member
override that implementation, add the override keyword. Otherwise add the new keyword."
"CS0219: The variable '__retval' is assigned but its value is never used."
"CS0628: 'ToggleSwitch.OnToggled()': new protected member declared in sealed type"
"CS0660: 'CustomEquals2' defines operator == or operator != but does not override Object.Equals(object o)"
"CA2257: The 'ABI.Windows.Foundation.Collections.IMapChangedEventArgs<K>.Vftbl' member on the 'ABI.Windows.Foundation.Collections.IMapChangedEventArgs<K>'
type should be marked 'static' as 'ABI.Windows.Foundation.Collections.IMapChangedEventArgs<K>' has the 'DynamicInterfaceImplementationAttribute' applied"
-->
<WarningsNotAsErrors>$(WarningsNotAsErrors);CS0108;CS0109;CS0114;CS0219;CS0628;CS0660;CA2257</WarningsNotAsErrors>

<!-- Projections should not require runtime marshalling. -->
<DisableRuntimeMarshalling>True</DisableRuntimeMarshalling>
Expand Down
21 changes: 17 additions & 4 deletions src/Projections/Test/TestHost.ProbeByHost.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
Expand Down Expand Up @@ -67,13 +68,17 @@ private static unsafe int Do_Abi_ActivateInstance_0(IntPtr thisPtr, out IntPtr i
return 0;
}
}
internal static ObjectReference<Vftbl> FromAbi(IntPtr thisPtr) => ObjectReference<Vftbl>.FromAbi(thisPtr);
internal static ObjectReference<Vftbl> FromAbi(IntPtr thisPtr) => ObjectReference<Vftbl>.FromAbi(thisPtr, global::WinRT.Interop.IID.IID_IActivationFactory);

public static implicit operator IActivationFactory(IObjectReference obj) => (obj != null) ? new IActivationFactory(obj) : null;
protected readonly ObjectReference<Vftbl> _obj;
public IObjectReference ObjRef { get => _obj; }
public IntPtr ThisPtr => _obj.ThisPtr;
public ObjectReference<I> AsInterface<I>() => _obj.As<I>();
public ObjectReference<I> AsInterface<
#if NET
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
#endif
I>() => _obj.As<I>();
public A As<A>() => _obj.AsType<A>();
public IActivationFactory(IObjectReference obj) : this(obj.As<Vftbl>()) { }
internal IActivationFactory(ObjectReference<Vftbl> obj)
Expand Down Expand Up @@ -114,7 +119,12 @@ internal class ActivationFactory : IActivationFactory
namespace WinRT
{
public static class Module
{
{
#if NET
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor, typeof(TestHost.ProbeByHost))]
[UnconditionalSuppressMessage("Trimming", "IL2057", Justification = "We're manually keeping the target type around.")]

#endif
public static unsafe IntPtr GetActivationFactory(String runtimeClassId)
{
if (string.CompareOrdinal(runtimeClassId, "TestHost.ProbeByHost") == 0)
Expand All @@ -138,7 +148,10 @@ public static unsafe IntPtr GetActivationFactory(String runtimeClassId)
namespace TestHost
{
public class ProbeByHost : IStringable
{
{
#if NET
[UnconditionalSuppressMessage("SingleFile", "IL3000", Justification = "We're not publishing this test as single file.")]
#endif
public override string ToString()
{
return new System.IO.FileInfo(Assembly.GetExecutingAssembly().Location).Name;
Expand Down
Loading