question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

GenAPI issues generate invalid C# for internal types

See original GitHub issue

We have encountered cases where we want to generate internal members in reference assemblies. It would be nice to be able to distinguish between private and internal members instead of the only --all option that accounts for both. However, given the current implementation, here are a few issues we have ran into. FYI @dougbu @wtgodbe @safern @tannergooding

  1. Null Argument Exceptions

For example, when generating for the field F:Microsoft.AspNetCore.Mvc.ApplicationModels.ActionAttributeRouteModel.<GetAttributeRoutes>d__3.{}2__current the following exception will be hit

Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'source')
     at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
     at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
     at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
     at Microsoft.Cci.Extensions.CSharp.CSharpCciExtensions.GetAttributeOfType(IEnumerable`1 attributes, String attributeName) in /_/src/Microsoft.Cci.Extensions/Extensions/CSharp/CSharpCciExtensions.cs:line 666
     at Microsoft.Cci.Extensions.CSharp.CSharpCciExtensions.GetValueTupleNames(IEnumerable`1 attributes) in /_/src/Microsoft.Cci.Extensions/Extensions/CSharp/CSharpCciExtensions.cs:line 683
     at Microsoft.Cci.Writers.CSharp.CSDeclarationWriter.WriteTypeName(ITypeReference type, Boolean noSpace, IEnumerable`1 attributes, Boolean useTypeKeywords, Boolean omitGenericTypeList) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.cs:line 272
     at Microsoft.Cci.Writers.CSharp.CSDeclarationWriter.WriteFieldDefinition(IFieldDefinition field) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.Fields.cs:line 56
     at Microsoft.Cci.Writers.CSharp.CSDeclarationWriter.WriteMemberDeclaration(ITypeDefinitionMember member) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.cs:line 180
     at Microsoft.Cci.Writers.CSharp.CSDeclarationWriter.WriteDeclaration(IDefinition definition) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSDeclarationWriter.cs:line 120
     at Microsoft.Cci.Writers.CSharpWriter.Visit(ITypeDefinitionMember member) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 244
     at Microsoft.Cci.Traversers.SimpleTypeMemberTraverser.Visit(IEnumerable`1 members) in /_/src/Microsoft.Cci.Extensions/Traversers/SimpleTypeMemberTraverser.cs:line 104
     at Microsoft.Cci.Writers.CSharpWriter.Visit(IEnumerable`1 members) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 147
     at Microsoft.Cci.Traversers.SimpleTypeMemberTraverser.Visit(ITypeDefinition parentType, IEnumerable`1 fields) in /_/src/Microsoft.Cci.Extensions/Traversers/SimpleTypeMemberTraverser.cs:line 117
     at Microsoft.Cci.Writers.CSharpWriter.Visit(ITypeDefinition parentType, IEnumerable`1 fields) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 211
     at Microsoft.Cci.Traversers.SimpleTypeMemberTraverser.Visit(ITypeDefinition type) in /_/src/Microsoft.Cci.Extensions/Traversers/SimpleTypeMemberTraverser.cs:line 74
     at Microsoft.Cci.Writers.CSharpWriter.Visit(ITypeDefinition type) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 137
     at Microsoft.Cci.Traversers.SimpleTypeMemberTraverser.Visit(IEnumerable`1 types) in /_/src/Microsoft.Cci.Extensions/Traversers/SimpleTypeMemberTraverser.cs:line 62
     at Microsoft.Cci.Writers.CSharpWriter.Visit(IEnumerable`1 types) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 116
     at Microsoft.Cci.Traversers.SimpleTypeMemberTraverser.Visit(ITypeDefinition type) in /_/src/Microsoft.Cci.Extensions/Traversers/SimpleTypeMemberTraverser.cs:line 79
     at Microsoft.Cci.Writers.CSharpWriter.Visit(ITypeDefinition type) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 137
     at Microsoft.Cci.Traversers.SimpleTypeMemberTraverser.Visit(IEnumerable`1 types) in /_/src/Microsoft.Cci.Extensions/Traversers/SimpleTypeMemberTraverser.cs:line 62
     at Microsoft.Cci.Writers.CSharpWriter.Visit(IEnumerable`1 types) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 116
     at Microsoft.Cci.Traversers.SimpleTypeMemberTraverser.Visit(INamespaceDefinition ns) in /_/src/Microsoft.Cci.Extensions/Traversers/SimpleTypeMemberTraverser.cs:line 55
     at Microsoft.Cci.Writers.CSharpWriter.Visit(INamespaceDefinition ns) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 105
     at Microsoft.Cci.Traversers.SimpleTypeMemberTraverser.Visit(IEnumerable`1 namespaces) in /_/src/Microsoft.Cci.Extensions/Traversers/SimpleTypeMemberTraverser.cs:line 43
     at Microsoft.Cci.Traversers.SimpleTypeMemberTraverser.Visit(IAssembly assembly) in /_/src/Microsoft.Cci.Extensions/Traversers/SimpleTypeMemberTraverser.cs:line 35
     at Microsoft.Cci.Writers.CSharpWriter.Visit(IAssembly assembly) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 91
     at Microsoft.Cci.Writers.CSharpWriter.WriteAssemblies(IEnumerable`1 assemblies) in /_/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs:line 79
     at Microsoft.DotNet.GenAPI.Program.<>c__DisplayClass0_0.<Main>b__0() in /_/src/Microsoft.DotNet.GenAPI/Program.cs:line 97
     at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
     at Microsoft.DotNet.GenAPI.Program.Main(String[] args) in /_/src/Microsoft.DotNet.GenAPI/Program.cs:line 165
  1. Anonymous classes

Anonymous classes are generated when the --all option is specified and the code is not compilable. We have to manually remove the anonymous classes:

    public static partial class DataProtectionProvider
    {
        public static Microsoft.AspNetCore.DataProtection.IDataProtectionProvider Create(System.IO.DirectoryInfo keyDirectory) { throw null; }
        public static Microsoft.AspNetCore.DataProtection.IDataProtectionProvider Create(System.IO.DirectoryInfo keyDirectory, System.Action<Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder> setupAction) { throw null; }
        public static Microsoft.AspNetCore.DataProtection.IDataProtectionProvider Create(System.IO.DirectoryInfo keyDirectory, System.Action<Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder> setupAction, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; }
        public static Microsoft.AspNetCore.DataProtection.IDataProtectionProvider Create(System.IO.DirectoryInfo keyDirectory, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; }
        public static Microsoft.AspNetCore.DataProtection.IDataProtectionProvider Create(string applicationName) { throw null; }
        public static Microsoft.AspNetCore.DataProtection.IDataProtectionProvider Create(string applicationName, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; }
        internal static Microsoft.AspNetCore.DataProtection.IDataProtectionProvider CreateProvider(System.IO.DirectoryInfo keyDirectory, System.Action<Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder> setupAction, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; }
        [System.Runtime.CompilerServices.CompilerGeneratedAttribute]
        private sealed partial class <>c
        {
            public static readonly Microsoft.AspNetCore.DataProtection.DataProtectionProvider.<>c __9;
            public static System.Action<Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder> __9__1_0;
            public static System.Action<Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder> __9__4_0;
            public <>c() { }
            private static void .cctor() { }
            internal void <Create>b__1_0(Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder builder) { }
            internal void <Create>b__4_0(Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder builder) { }
        }
        [System.Runtime.CompilerServices.CompilerGeneratedAttribute]
        private sealed partial class <>c__DisplayClass0_0
        {
            public string applicationName;
            public <>c__DisplayClass0_0() { }
            internal void <Create>b__0(Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder builder) { }
        }
        [System.Runtime.CompilerServices.CompilerGeneratedAttribute]
        private sealed partial class <>c__DisplayClass3_0
        {
            public string applicationName;
            public <>c__DisplayClass3_0() { }
            internal void <Create>b__0(Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder builder) { }
        }
    }
  1. Private static constructors

Non-compilable private static constructor are generated, which we have to remove manually:

    internal static partial class EncodingUtil
    {
        public static readonly System.Text.UTF8Encoding SecureUtf8Encoding;
        private static void .cctor() { }
    }
  1. Unsafe interfaces missing the unsafe keyword:

Implementation C# source:

    internal unsafe interface IBCryptGenRandom
    {
        void GenRandom(byte* pbBuffer, uint cbBuffer);
    }

Generated reference C# source

    internal partial interface IBCryptGenRandom
    {
        void GenRandom(byte* pbBuffer, uint cbBuffer);
    }
  1. Nullable types not generated

It seems like some nullable types are not generated as such by GenAPI. It doesn’t happen for all nullable types so it’s unclear what exactly causes the errors.

Implementation C# source:


namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
#nullable enable
    internal abstract class ResourceInvoker
    {
        protected readonly DiagnosticListener _diagnosticListener;
        protected readonly ILogger _logger;
        protected readonly IActionContextAccessor _actionContextAccessor;
        protected readonly IActionResultTypeMapper _mapper;
        protected readonly ActionContext _actionContext;
        protected readonly IFilterMetadata[] _filters;
        protected readonly IList<IValueProviderFactory> _valueProviderFactories;

        private AuthorizationFilterContextSealed? _authorizationContext;
        private ResourceExecutingContextSealed? _resourceExecutingContext;
        private ResourceExecutedContextSealed? _resourceExecutedContext;
        private ExceptionContextSealed? _exceptionContext;
        private ResultExecutingContextSealed? _resultExecutingContext;
        private ResultExecutedContextSealed? _resultExecutedContext;

        // Do not make this readonly, it's mutable. We don't want to make a copy.
        // https://blogs.msdn.microsoft.com/ericlippert/2008/05/14/mutating-readonly-structs/
        protected FilterCursor _cursor;
        protected IActionResult? _result;
        protected object? _instance;
...
}

Generated reference C# source


    [System.Runtime.CompilerServices.NullableAttribute((byte)0)]
    [System.Runtime.CompilerServices.NullableContextAttribute((byte)1)]
    internal abstract partial class ResourceInvoker
    {
        protected readonly Microsoft.AspNetCore.Mvc.ActionContext _actionContext;
        protected readonly Microsoft.AspNetCore.Mvc.Infrastructure.IActionContextAccessor _actionContextAccessor;
        [System.Runtime.CompilerServices.NullableAttribute((byte)2)]
        private Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.AuthorizationFilterContextSealed _authorizationContext;
        protected Microsoft.AspNetCore.Mvc.Filters.FilterCursor _cursor;
        protected readonly System.Diagnostics.DiagnosticListener _diagnosticListener;
        [System.Runtime.CompilerServices.NullableAttribute((byte)2)]
        private Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ExceptionContextSealed _exceptionContext;
        protected readonly Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata[] _filters;
        [System.Runtime.CompilerServices.NullableAttribute((byte)2)]
        protected object _instance;
        protected readonly Microsoft.Extensions.Logging.ILogger _logger;
        protected readonly Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultTypeMapper _mapper;
        [System.Runtime.CompilerServices.NullableAttribute((byte)2)]
        private Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResourceExecutedContextSealed _resourceExecutedContext;
        [System.Runtime.CompilerServices.NullableAttribute((byte)2)]
        private Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResourceExecutingContextSealed _resourceExecutingContext;
        [System.Runtime.CompilerServices.NullableAttribute((byte)2)]
        protected Microsoft.AspNetCore.Mvc.IActionResult _result;
        [System.Runtime.CompilerServices.NullableAttribute((byte)2)]
        private Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultExecutedContextSealed _resultExecutedContext;
        [System.Runtime.CompilerServices.NullableAttribute((byte)2)]
        private Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultExecutingContextSealed _resultExecutingContext;
        protected readonly System.Collections.Generic.IList<Microsoft.AspNetCore.Mvc.ModelBinding.IValueProviderFactory> _valueProviderFactories;
...
}

In this case, it looks like NullableAttribute is added to the nullable types but the types are not nullable themselves. Is this an oversight or a feature that we are misunderstanding?

To repro these issues, find the implementation projects containing the code I’ve pasted here and run dotnet msbuild /t:GenerateReferenceSource to run genAPI to produce the generated code.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:17 (16 by maintainers)

github_iconTop GitHub Comments

1reaction
ericstjcommented, Dec 6, 2019

For Nullable this was all a recent addition made by @safern. You are probably using an old version of GenAPI.

@dougbu it’s reasonable to have a new filter that is public + internals-only-when-IVT is used. This shouldn’t be the default public filter though since that would break folks who use GenAPI and only use IVT for runtime assemblies and testing.

0reactions
dougbucommented, Apr 2, 2020

All but “Nullable types not generated” addressed in d6dd7a000fe9. Already have a number of issues related to nullability elsewhere in this repo and that point feels redundant.

Read more comments on GitHub >

github_iconTop Results From Across the Web

GenICam GenTL Standard
Figure 2-3: GenICam GenTL interface (C and GenApi Feature-interface). The GenTL Producer driver consists of three logical parts: the C ...
Read more >
GenICam Standard
The GenApi module deals with the problem of how to configure a camera. The key idea is to make camera manufacturers provide machine...
Read more >
Programming with pylon C | Basler Product Documentation
A transport layer is strictly an internal concept of the pylon C API that application ... The stream grabber becomes invalid after closing...
Read more >
Image Acquisition Interface for GenICam GenTL compliant ...
Fixed a problem with the automatic update of the parameters Width, Height, PayloadSize and AcquisitionMode due to incorrect handling of internal GenApi ......
Read more >
Spinnaker C++: Camera Class Reference
Generates an internal trigger if Trigger Source is set to Software. More. ... Description: Returns the unique identifier of the Exposure End type...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found