microsoft / CsWin32

A source generator to add a user-defined set of Win32 P/Invoke methods and supporting types to a C# project.
MIT License
1.99k stars 84 forks source link

Code Quality: Use `WinMdRoot` instead of `winmdroot` to supress CS8981 (type name is ASCII lowercase only) #1214

Closed 0x5bfa closed 1 week ago

0x5bfa commented 1 week ago

I'm seeing an warning describes CS8981 - The type name only contains lower-cased ascii characters.

image

-#pragma warning disable CS1591,CS1573,CS0465,CS0649,CS8019,CS1570,CS1584,CS1658,CS0436
+#pragma warning disable CS1591,CS1573,CS0465,CS0649,CS8019,CS1570,CS1584,CS1658,CS0436,CS8981
AArnott commented 1 week ago

CsWin32 already suppresses CS8981. Are you reporting that there are generated code files that omit that suppression? If so, can you share the full content of the file, or at least the file name of the generated file?

0x5bfa commented 1 week ago

The full project code is in https://github.com/files-community/Files I'm seeing a bunch of it.

image

As a sample (HRESULT):

// ------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------

#pragma warning disable CS1591,CS1573,CS0465,CS0649,CS8019,CS1570,CS1584,CS1658,CS0436,CS8981
using global::System;
using global::System.Diagnostics;
using global::System.Diagnostics.CodeAnalysis;
using global::System.Runtime.CompilerServices;
using global::System.Runtime.InteropServices;
using global::System.Runtime.Versioning;
using winmdroot = global::Windows.Win32;
namespace Windows.Win32
{
    namespace Foundation
    {
        /// <remarks>
        /// <para>The **HRESULT** data type is the same as the [SCODE](scode.md) data type. An **HRESULT** value consists of the following fields: - A 1-bit code indicating severity, where zero represents success and 1 represents failure. - A 4-bit reserved value. - An 11-bit code indicating responsibility for the error or warning, also known as a facility code. - A 16-bit code describing the error or warning. Most MAPI interface methods and functions return **HRESULT** values to provide detailed cause formation. **HRESULT** values are also used widely in OLE interface methods. OLE provides several macros for converting between **HRESULT** values and **SCODE** values, another common data type for error handling. > [!NOTE] > In 64-bit MAPI, **HRESULT** is still a 32-bit value. For information about the OLE use of **HRESULT** values, see the  *OLE Programmer's Reference*. For more information about the use of these values in MAPI, see [Error Handling](error-handling-in-mapi.md) and any of the following interface methods: [IABLogon::GetLastError](iablogon-getlasterror.md) [IMAPISupport::GetLastError](imapisupport-getlasterror.md) [IMAPIControl::GetLastError](imapicontrol-getlasterror.md) [IMAPITable::GetLastError](imapitable-getlasterror.md) [IMAPIProp::GetLastError](imapiprop-getlasterror.md) [IMAPIViewAdviseSink::OnPrint](imapiviewadvisesink-onprint.md)</para>
        /// <para><see href="https://learn.microsoft.com/office/client-developer/outlook/mapi/hresult#">Read more on docs.microsoft.com</see>.</para>
        /// </remarks>
        [DebuggerDisplay("{Value}")]
        [global::System.CodeDom.Compiler.GeneratedCode("Microsoft.Windows.CsWin32", "0.3.49-beta+91f5c15987")]
        public readonly partial struct HRESULT
            : IEquatable<HRESULT>
        {
            public readonly int Value;

            public HRESULT(int value) => this.Value = value;

            public static implicit operator int(HRESULT value) => value.Value;

            public static explicit operator HRESULT(int value) => new HRESULT(value);

            public static bool operator ==(HRESULT left, HRESULT right) => left.Value == right.Value;

            public static bool operator !=(HRESULT left, HRESULT right) => !(left == right);

            public bool Equals(HRESULT other) => this.Value == other.Value;

            public override bool Equals(object obj) => obj is HRESULT other && this.Equals(other);

            public override int GetHashCode() => this.Value.GetHashCode();

            public override string ToString() => string.Format(global::System.Globalization.CultureInfo.InvariantCulture, "0x{0:X8}", this.Value);

            public static implicit operator uint(HRESULT value) => (uint)value.Value;

            public static explicit operator HRESULT(uint value) => new HRESULT((int)value);

            [DebuggerBrowsable(DebuggerBrowsableState.Never)]
            public bool Succeeded => this.Value >= 0;

            [DebuggerBrowsable(DebuggerBrowsableState.Never)]
            public bool Failed => this.Value < 0;

            public HRESULT ThrowOnFailure(IntPtr errorInfo = default)

            {
                Marshal.ThrowExceptionForHR(this.Value, errorInfo);
                return this;
            }

            public string ToString(string format, IFormatProvider formatProvider) => ((uint)this.Value).ToString(format, formatProvider);
        }
    }
}
AArnott commented 1 week ago

Thanks for the details. I'm very surprised that the same file that suppresses the warning is still emitting it. I want to get to the bottom of this for you because seeing all those warnings in your regular builds is not something you should have to deal with. I'll do some digging.

AArnott commented 1 week ago

The warnings are coming from Files.App.Server.csproj, which is using a very old version of CsWin32. When I update it to 0.3.49-beta to match the version consumed by the Files.App.csproj, the warnings go away. Unfortunately, a few new errors appear with that upgrade because the generated code APIs have changed. I submitted a PR to Files to get it updated.

0x5bfa commented 1 week ago

Omg, thank you so much!! And sorry for the confusion.