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

WinRTTypeWriter generator fails with NullReferenceException #1369

Closed
Sergio0694 opened this issue Oct 22, 2023 · 2 comments · Fixed by #1394
Closed

WinRTTypeWriter generator fails with NullReferenceException #1369

Sergio0694 opened this issue Oct 22, 2023 · 2 comments · Fixed by #1394
Labels
authoring Related to authoring feature work bug Something isn't working

Comments

@Sergio0694
Copy link
Member

Describe the bug

It seems there's a NRE bug in the "WinRTTypeWriter" generator, at least in some scenarios.
Might be fixed already with all the changes in the AOT branch, but figured I'd report just for tracking 🙂

To Reproduce

  1. Checkout to Sergio0694/ComputeSharp@79ff77b
  2. Build the ComputeSharp.NativeLibrary.WinRT project

It's failing for me both when building from VS and when trying to build with msbuild from a developer command prompt.

CSC : error CS8785: Generator 'SourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'NullReferenceException' with message 'Object reference not set to an instance of an object.'.

Error	CS8785	Generator 'SourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'NullReferenceException' with message 'Object reference not set to an instance of an object.'.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Generator.WinRTTypeWriter.QualifiedName(ISymbol symbol, Boolean includeGenerics)
   at Generator.WinRTTypeWriter.EncodeSymbol(Symbol symbol, SignatureTypeEncoder typeEncoder)
   at Generator.WinRTTypeWriter.EncodeParameters(Parameter[] parameters, ParametersEncoder parametersEncoder)
   at Generator.WinRTTypeWriter.<>c__DisplayClass65_0.<AddMethodReference>b__1(ParametersEncoder parametersEncoder)
   at System.Reflection.Metadata.Ecma335.MethodSignatureEncoder.Parameters(Int32 parameterCount, Action`1 returnType, Action`1 parameters)
   at Generator.WinRTTypeWriter.AddMethodReference(String name, Parameter[] parameters, Symbol returnSymbol, INamedTypeSymbol parentType, Boolean isStatic)
   at Generator.WinRTTypeWriter.AddMethodReference(IMethodSymbol method)
   at Generator.WinRTTypeWriter.AddProjectedType(INamedTypeSymbol type, String projectedTypeOverride)
   at Generator.WinRTTypeWriter.AddType(INamedTypeSymbol type, Boolean treatAsProjectedType)
   at Generator.WinRTTypeWriter.FinalizeGeneration()
   at Generator.ComponentGenerator.Generate()
   at Generator.SourceGenerator.Execute(GeneratorExecutionContext context)
   at Microsoft.CodeAnalysis.SourceGeneratorAdaptor.<Initialize>b__5_5(SourceProductionContext productionContext, GeneratorContextBuilder contextBuilder)
   at Microsoft.CodeAnalysis.UserFunctionExtensions.<>c__DisplayClass3_0`2.<WrapUserAction>b__0(TInput1 input1, TInput2 input2, CancellationToken token)Active	

Expected behavior

Project should build correctly.

Version Info

  • net8.0-windows10.0.22621.0
  • CsWinRT 2.0.4
@Sergio0694 Sergio0694 added the bug Something isn't working label Oct 22, 2023
@Sergio0694 Sergio0694 changed the title WinRTTypeWriter generator fails with NullReferenceException when building WinRTTypeWriter generator fails with NullReferenceException Oct 22, 2023
@Sergio0694
Copy link
Member Author

@manodasanW I've investigated this some more (with help from @hez2010 to create a local package from #1377 so I could also debug the generator), and think we've figured out what the problem is). The NullReferenceException is this one:

image

With the symbol being of type ABI.Microsoft.Graphics.Canvas.ICanvasDevice**:

image

Now, of course, this is not a valid WinRT type. The reason issue is this type shouldn't have been processed at all.

What's happening is that my type is implementing this ICanvasImageInterop.Interface interface, which is classic COM. However as discovered in #1283 (comment), CsWinRT needs this to have the [WindowsRuntimeType] attribute, or it will completely ignore the interface and not generate the correct vtable for the CCW scenario, which of course then results in failures when trying to pass such objects to native:

image

However, having this attribute makes the WinRT generator treat this type as a projected type, which of course isn't valid:

public static bool IsWinRTType(ISymbol type)
{
bool isProjectedType = type.GetAttributes().
Any(attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WindowsRuntimeTypeAttribute") == 0) ||
IsFundamentalType(type);

It seems the WinRT authoring scenario when there's also mixed classic COM interfaces is just broken (also related to #1283).


Any thoughts on how to fix it? I'm thinking a possible approach could be to add a bool IsClassicCOM property to [WindowsRuntimeType]. Then people could set that to true when using the attribute on an interface only implementing a classic COM type. The CsWinRT runtime would ignore it and just do the same thing it does today, but the generator could check that and skip the interface entirely, as it shouldn't show up in the WinMD metadata at all (since it's just COM).

That's just an idea, I'm sure there's other possible solutions too. What do you think?

@Sergio0694
Copy link
Member Author

Fixed by #1394, closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
authoring Related to authoring feature work bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants