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

Start using CsWin32 in System.Drawing.Common #10320

Closed
wants to merge 5 commits into from

Conversation

elachlan
Copy link
Contributor

@elachlan elachlan commented Nov 16, 2023

Related: #9879

Microsoft Reviewers: Open in CodeFlow

@ghost ghost assigned elachlan Nov 16, 2023
@elachlan
Copy link
Contributor Author

@JeremyKuhne I've linked directly to some files in System.Windows.Forms.Primitives here. I have some weird warnings around xml comments being unable to resolve crefs and I am unsure on how to resolve them.

@elachlan
Copy link
Contributor Author

Cc: @lonitra

@ghost ghost added the draft draft PR label Nov 16, 2023
@JeremyKuhne
Copy link
Member

@elachlan can you please share the warnings you're getting?

@elachlan
Copy link
Contributor Author

elachlan commented Nov 16, 2023

Here are the errors. I think the System.Drawing internal types are being picked up by System.Windows.Forms?

D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(101,73): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IOleInPlaceActiveObject.OnFrameWindowActivate(BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(101,27): error CS1574: XML comment has cref attribute 'OnFrameWindowActivate(BOOL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(109,71): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IOleInPlaceActiveObject.OnDocWindowActivate(BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(109,27): error CS1574: XML comment has cref attribute 'OnDocWindowActivate(BOOL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(119,93): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IOleInPlaceActiveObject.ResizeBorder(RECT*, IOleInPlaceUIWindow*, BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(119,27): error CS1574: XML comment has cref attribute 'ResizeBorder(RECT*, IOleInPlaceUIWindow*, BOOL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(126,66): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IOleInPlaceActiveObject.EnableModeless(BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(126,27): error CS1574: XML comment has cref attribute 'EnableModeless(BOOL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(133,48): error CS1580: Invalid type for parameter HWND* in XML comment cref attribute: 'IOleWindow.GetWindow(HWND*)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(133,27): error CS1574: XML comment has cref attribute 'GetWindow(HWND*)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(142,59): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IOleWindow.ContextSensitiveHelp(BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(142,27): error CS1574: XML comment has cref attribute 'ContextSensitiveHelp(BOOL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(214,51): error CS1580: Invalid type for parameter PCWSTR in XML comment cref attribute: 'IOleObject.SetHostNames(PCWSTR, PCWSTR)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(214,59): error CS1580: Invalid type for parameter PCWSTR in XML comment cref attribute: 'IOleObject.SetHostNames(PCWSTR, PCWSTR)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(214,27): error CS1574: XML comment has cref attribute 'SetHostNames(PCWSTR, PCWSTR)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(251,68): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IOleObject.InitFromData(ComIDataObject*, BOOL, uint)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(251,27): error CS1574: XML comment has cref attribute 'InitFromData(ComIDataObject*, BOOL, uint)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(271,78): error CS1580: Invalid type for parameter HWND in XML comment cref attribute: 'IOleObject.DoVerb(int, MSG*, IOleClientSite*, int, HWND, RECT*)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(271,27): error CS1574: XML comment has cref attribute 'DoVerb(int, MSG*, IOleClientSite*, int, HWND, RECT*)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(468,48): error CS1580: Invalid type for parameter HWND* in XML comment cref attribute: 'IOleWindow.GetWindow(HWND*)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(468,27): error CS1574: XML comment has cref attribute 'GetWindow(HWND*)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(471,59): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IOleWindow.ContextSensitiveHelp(BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(471,27): error CS1574: XML comment has cref attribute 'ContextSensitiveHelp(BOOL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(517,67): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IPersistPropertyBag.Save(IPropertyBag*, BOOL, BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(517,73): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IPersistPropertyBag.Save(IPropertyBag*, BOOL, BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(517,27): error CS1574: XML comment has cref attribute 'Save(IPropertyBag*, BOOL, BOOL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(569,59): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IPersistStorage.Save(IStorage*, BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(569,27): error CS1574: XML comment has cref attribute 'Save(IStorage*, BOOL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(633,61): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IPersistStreamInit.Save(IStream*, BOOL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(633,27): error CS1574: XML comment has cref attribute 'Save(IStream*, BOOL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(702,83): error CS1580: Invalid type for parameter HDC in XML comment cref attribute: 'IViewObject.Draw(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, HDC, RECTL*, RECTL*, nint, nuint)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(702,88): error CS1580: Invalid type for parameter HDC in XML comment cref attribute: 'IViewObject.Draw(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, HDC, RECTL*, RECTL*, nint, nuint)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(702,27): error CS1574: XML comment has cref attribute 'Draw(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, HDC, RECTL*, RECTL*, nint, nuint)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(733,90): error CS1580: Invalid type for parameter HDC in XML comment cref attribute: 'IViewObject.GetColorSet(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, LOGPALETTE**)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(733,27): error CS1574: XML comment has cref attribute 'GetColorSet(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, LOGPALETTE**)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(776,83): error CS1580: Invalid type for parameter HDC in XML comment cref attribute: 'IViewObject.Draw(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, HDC, RECTL*, RECTL*, nint, nuint)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(776,88): error CS1580: Invalid type for parameter HDC in XML comment cref attribute: 'IViewObject.Draw(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, HDC, RECTL*, RECTL*, nint, nuint)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(776,27): error CS1574: XML comment has cref attribute 'Draw(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, HDC, RECTL*, RECTL*, nint, nuint)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(800,90): error CS1580: Invalid type for parameter HDC in XML comment cref attribute: 'IViewObject.GetColorSet(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, LOGPALETTE**)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Control_ActiveXControlInterfaces.cs(800,27): error CS1574: XML comment has cref attribute 'GetColorSet(DVASPECT, int, void*, DVTARGETDEVICE*, HDC, LOGPALETTE**)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Internal\DrawingEventFlags.cs(24,54): error CS0419: Ambiguous reference in cref attribute: 'HDC'. Assuming 'HDC', but could have also matched other overloads including 'HDC'. [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Internal\Gdi\GdiCache.cs(19,29): error CS0419: Ambiguous reference in cref attribute: 'HDC'. Assuming 'HDC', but could have also matched other overloads including 'HDC'. [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Internal\Gdi\GdiCache.cs(24,39): error CS0419: Ambiguous reference in cref attribute: 'HDC'. Assuming 'HDC', but could have also matched other overloads including 'HDC'. [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\Internal\Gdi\GdiCache.cs(37,105): error CS0419: Ambiguous reference in cref attribute: 'HDC'. Assuming 'HDC', but could have also matched other overloads including 'HDC'. [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\RichTextBox.OleCallback.cs(90,107): error CS1580: Invalid type for parameter BOOL in XML comment cref attribute: 'IRichEditOleCallback.QueryAcceptData(Com.IDataObject*, ushort*, RECO_FLAGS, BOOL, HGLOBAL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\RichTextBox.OleCallback.cs(90,113): error CS1580: Invalid type for parameter HGLOBAL in XML comment cref attribute: 'IRichEditOleCallback.QueryAcceptData(Com.IDataObject*, ushort*, RECO_FLAGS, BOOL, HGLOBAL)' [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]
D:\a\_work\1\s\src\System.Windows.Forms\src\System\Windows\Forms\RichTextBox.OleCallback.cs(90,31): error CS1574: XML comment has cref attribute 'QueryAcceptData(Com.IDataObject*, ushort*, RECO_FLAGS, BOOL, HGLOBAL)' that could not be resolved [D:\a\_work\1\s\src\System.Windows.Forms\src\System.Windows.Forms.csproj]

@gpetrou
Copy link
Contributor

gpetrou commented Nov 17, 2023

Maybe the common files such as GetDcScope.cs should be moved to the Common\src folder and use the Compile Include in both projects?

@@ -173,7 +173,7 @@ public static Font DefaultFont
Font? defaultFont = null;

// For Arabic systems, always return Tahoma 8.
if ((ushort)Kernel32.GetSystemDefaultLCID() == 0x0001)
if ((ushort)PInvoke.GetSystemDefaultLCID() == 0x0001)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps add some constants for these hardcoded values? I see https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/63d3d639-7fd2-4afb-abbe-0d5b5551eef8 has a table with them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine there is one from cswin32.

Copy link
Contributor

@DJm00n DJm00n Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there should be GetSystemDefaultLocaleName() call and compare with "ar" call instead. LCIDs are deprecated.

@elachlan
Copy link
Contributor Author

Maybe the common files such as GetDcScope.cs should be moved to the Common\src folder and use the Compile Include in both projects?

That was the plan. But I didn't want to move stuff quite yet. I was also wanting to work out folder structure in common if we move a lot of code files there.

@elachlan
Copy link
Contributor Author

Related:
dotnet/roslyn#4033
dotnet/roslyn#51013

@elachlan
Copy link
Contributor Author

@jaredpar we are currently running into lots of warnings along the lines of warning CS0419: Ambiguous reference in cref attribute: 'HDC'. Assuming 'HDC', but could have also matched other overloads including 'HDC'.

System.Drawing.Common is referenced by System.Windows.Forms.Primitives which has InternalsVisibleTo System.Windows.Forms.

The Primitives project is basically a container project for the Interop code.

Just wondering how we can get unblocked here.

@elachlan
Copy link
Contributor Author

@AArnott have you got any ideas? Can we even use CsWin32 in two different projects at the same time without issue?

@AArnott
Copy link
Contributor

AArnott commented Nov 21, 2023

@elachlan Absolutely. CsWin32 can work on as many projects as you have.

But InternalsVisibleTo causes so many problems, I never use it. CsWin32 already has the smarts to tell when a project you reference declares a type that it would emit. If your compilation can access that type (either because it's public or because it's internal and you have IVT to it), CsWin32 won't re-emit the type in order to avoid type reference ambiguities and ensure you can use them as exchange types.

Here is a sample that shows this. It has two projects, both wanting HDC to be emitted. But only one project gets it, and the other inherits it. If you comment out the IVT attribute, then suddenly both projects will emit it.
CsWin32Sandbox2Project.zip

@elachlan
Copy link
Contributor Author

@JeremyKuhne Basically, the issue here is that the namespaces for cswin32 generated code are the same for both Drawing and Primitives. When the xml comments try and resolve types, they ignore accessibility. So we get a conflict. Drawing does not use InternalsVisibleTo, which I thought meant it should be fine. Apparently not.

Only work around I see is aliasing the clashing types. Which isn't really scalable. Failing that, I think we would need to have a shared primitives project and move any Drawing dependent code (some of the helpers implemented in partials) into Forms, but I am unsure if that would solve it.

@AArnott
Copy link
Contributor

AArnott commented Nov 28, 2023

When the xml comments try and resolve types, they ignore accessibility

This doesn't gel with my experimentation.
ConsoleApp1.zip

That solution has two projects, both consume CsWin32 types that they generate. And an xml doc comment in the referencing project has a type reference to the CsWin32 type that they both generate, and there is no type resolution ambiguity warning emitted.

@elachlan
Copy link
Contributor Author

I tried to reproduce the issue in the attached project, but haven't been successful so far.

@JeremyKuhne
Copy link
Member

@jaredpar can you help connect me to the right person for this? It seems to be confined to however XML comments are resolving crefs.

@JeremyKuhne
Copy link
Member

System.Drawing has no [InternalsVisibleTo] so this doesn't make much sense to me.

Project references: System.Drawing.Common <- System.Windows.Forms.Interop <- System.Windows.Forms

System.Windows.Forms.Interop currently has CsWin32 code generation (all internal), has InternalsVisibleTo to System.Windows.Forms. Adding CsWin32 to System.Drawing.Common (all internal) now causes crefs to fail for types that are defined in both projects in System.Windows.Forms.

@jaredpar
Copy link
Member

System.Drawing has no [InternalsVisibleTo] so this doesn't make much sense to me.

The [InternalsVisibleTo] is a red herring. The core issue is that XML doc comments do not respect accessibility limitations. An XML doc comment is free to refer to members in another assembly regardless of accessibility. The only limitation is that they cannot access private members. This is likely surprising to most developers but it's behavior that goes back to the C# 1.0 compiler. The only change has been in C# 7 era we removed the ability for XML docs to access private state.

The reason you're seeing these errors now is that after this change there are two referenced assemblies that defined HWND, BOOL, etc ... with the same fully qualified name. The XML doc comment engine is looking up these types and finding two definitions with the same fully qualified name, there is no way to break this tie so it issues an error. This worked before because System.Drawing.Common defined BOOL in a diff namespace than System.Windows.Forms.Primitives hence compiler could pick a winner based on namespace lookup rules.

As for how to move forward there are not a lot of good options. I could not find a good way to suppress the CS0433 warnings that lead to the XML doc ambiguity issues being surfaced (could just be ignorance on my part as XML doc is not my strong suit but simple suppressions aren't considered in this process). Short term you may need to remove the XML doc comments that are triggering these issues, or redefine the types in the current assembly so the compiler can break the tie (but that likely has other negative consquences you don't want).

Longer term I think we likely need to revisit this behavior in XML doc processing. It's effectively implicit IVT to all your references. The increasing popularity of tools like CsWin32 have generators that emit the same fully qualified name in all consuming projects are making this existing issue more prevalent. Yet it can't be changed on a whim because there are existing customers that depend on it. It may be a behavior change we can tie to langversion though. Will need to dig into the details a bit on that. Unfortunately it's the time of year where we lack critical mass to discuss this so it will likely have to wait until people return from the holidays.

Note: Want to be clear I think CsWin23 code generation strategy is completely rationale here. The issue is XML docs having implicit IVT to everything.

@JeremyKuhne
Copy link
Member

JeremyKuhne commented Dec 18, 2023

I experimented with adding an additional interop assembly to contain shared types so there would be no ambiguity. While I can create this and build it fine, XML comment crefs still can't figure out types that are only defined once in the referenced project.

So:

System.Windows.Primitives -> System.Windows.Forms.Primitives -> System.Windows->Forms
System.Windows.Primitives -> System.Drawing.Common -> System.Windows.Forms.Primitives

HWND, etc. defined in System.Windows.Primitives.

Note that in order to do this you have to pass the TargetFramework to the shared project from System.Drawing.Common as it is multitargeting.

System.Windows.Primitives:

  <PropertyGroup>
    <AssemblyName>System.Windows.Primitives</AssemblyName>
    <TargetFrameworks>$(NetCurrent);$(NetPrevious);$(NetMinimum)</TargetFrameworks>

System.Drawing.Common:

    <ProjectReference Include="..\..\System.Windows.Primitives\src\System.Windows.Primitives.csproj" >
      <SetTargetFramework>TargetFramework=$(TargetFramework)</SetTargetFramework>
    </ProjectReference>

@elachlan
Copy link
Contributor Author

I guess we have to wait for a solution from the compiler team? Maybe an escape hatch to only include internals when visible.

@sharwell
Copy link
Member

sharwell commented Jan 2, 2024

You can resolve issues in cref attributes by adding a using alias:

using BOOL = Namespace.Of.BOOL;

The cref will resolve against the using alias before attempting to resolve against metadata imports, and the using alias directive will respect accessibility.

@elachlan
Copy link
Contributor Author

elachlan commented Jan 2, 2024

You can resolve issues in cref attributes by adding a using alias:

using BOOL = Namespace.Of.BOOL;

The cref will resolve against the using alias before attempting to resolve against metadata imports, and the using alias directive will respect accessibility.

I think I tried this but had issues with Global Usings.

@sharwell
Copy link
Member

sharwell commented Jan 3, 2024

@elachlan Can I push a small fix to this PR?

@JeremyKuhne
Copy link
Member

@sharwell can you share what you are thinking first, instead of pushing directly? I'm hesitant to manually create aliases for every conflicting type.

@sharwell
Copy link
Member

sharwell commented Jan 3, 2024

@JeremyKuhne I'm going to push the change based on the 👍 from @elachlan and the fact that this is a draft where it can be easily removed if you don't like it

@@ -18,6 +18,7 @@
using static Interop;
using ComTypes = System.Runtime.InteropServices.ComTypes;
using Encoding = System.Text.Encoding;
using HandleRef_HWND = HandleRef<Windows.Win32.Foundation.HWND>;
Copy link
Member

@sharwell sharwell Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Limited choices here because HandleRef<T> is defined in the global namespace and dotnet/roslyn#116 doesn't appear to be moving forward

global using HDC = Windows.Win32.Graphics.Gdi.HDC;
global using HGLOBAL = Windows.Win32.Foundation.HGLOBAL;
global using HWND = Windows.Win32.Foundation.HWND;
global using PCWSTR = Windows.Win32.Foundation.PCWSTR;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Only need aliases for items that appear by name in cref attributes. Note that for each alias, there is also a global using directive for the containing namespace so the alias will never be accessible in a code location where the target of the alias would not already be accessible.

@elachlan
Copy link
Contributor Author

elachlan commented Jan 6, 2024

Closing in favor of #10598

@elachlan elachlan closed this Jan 6, 2024
@elachlan elachlan deleted the System.Drawing.Common-CsWin32 branch January 9, 2024 00:16
@github-actions github-actions bot locked and limited conversation to collaborators Feb 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
draft draft PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants