@@ -435,6 +435,7 @@ public void Close()
435
435
GenerateNativeBitfieldAttribute ( this , stream , leaveStreamOpen ) ;
436
436
GenerateNativeInheritanceAttribute ( this , stream , leaveStreamOpen ) ;
437
437
GenerateNativeTypeNameAttribute ( this , stream , leaveStreamOpen ) ;
438
+ GenerateNativeAnnotationAttribute ( this , stream , leaveStreamOpen ) ;
438
439
GenerateSetsLastSystemErrorAttribute ( this , stream , leaveStreamOpen ) ;
439
440
GenerateVtblIndexAttribute ( this , stream , leaveStreamOpen ) ;
440
441
GenerateTransparentStructs ( this , stream , leaveStreamOpen ) ;
@@ -795,6 +796,96 @@ static void GenerateNativeTypeNameAttribute(PInvokeGenerator generator, Stream?
795
796
}
796
797
}
797
798
799
+ static void GenerateNativeAnnotationAttribute ( PInvokeGenerator generator , Stream ? stream , bool leaveStreamOpen )
800
+ {
801
+ const string AttributeName = "NativeAnnotationAttribute" ;
802
+ var config = generator . Config ;
803
+
804
+ var ns = generator . GetNamespace ( AttributeName ) ;
805
+ if ( config . ExcludedNames . Contains ( AttributeName ) || config . ExcludedNames . Contains ( $ "{ ns } .{ AttributeName } ") )
806
+ {
807
+ return ;
808
+ }
809
+
810
+ if ( stream is null )
811
+ {
812
+ var outputPath = Path . Combine ( config . OutputLocation , $ "{ AttributeName } .cs") ;
813
+ stream = generator . _outputStreamFactory ( outputPath ) ;
814
+ }
815
+
816
+ using var sw = new StreamWriter ( stream , s_defaultStreamWriterEncoding , DefaultStreamWriterBufferSize , leaveStreamOpen ) ;
817
+ sw . NewLine = "\n " ;
818
+
819
+ if ( ! string . IsNullOrEmpty ( config . HeaderText ) )
820
+ {
821
+ sw . WriteLine ( config . HeaderText ) ;
822
+ }
823
+
824
+ var indentString = " " ;
825
+
826
+ sw . WriteLine ( "using System;" ) ;
827
+ sw . WriteLine ( "using System.Diagnostics;" ) ;
828
+ sw . WriteLine ( ) ;
829
+
830
+ sw . Write ( "namespace " ) ;
831
+ sw . Write ( ns ) ;
832
+
833
+ if ( generator . Config . GenerateFileScopedNamespaces )
834
+ {
835
+ sw . WriteLine ( ';' ) ;
836
+ sw . WriteLine ( ) ;
837
+ indentString = "" ;
838
+ }
839
+ else
840
+ {
841
+ sw . WriteLine ( ) ;
842
+ sw . WriteLine ( '{' ) ;
843
+ }
844
+
845
+ sw . Write ( indentString ) ;
846
+ sw . WriteLine ( "/// <summary>Defines the annotation found in a native declaration.</summary>" ) ;
847
+ sw . Write ( indentString ) ;
848
+ sw . WriteLine ( "[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]" ) ;
849
+ sw . Write ( indentString ) ;
850
+ sw . WriteLine ( "[Conditional(\" DEBUG\" )]" ) ;
851
+ sw . Write ( indentString ) ;
852
+ sw . WriteLine ( $ "internal sealed partial class { AttributeName } : Attribute") ;
853
+ sw . Write ( indentString ) ;
854
+ sw . WriteLine ( '{' ) ;
855
+ sw . Write ( indentString ) ;
856
+ sw . WriteLine ( " private readonly string _annotation;" ) ;
857
+ sw . WriteLine ( ) ;
858
+ sw . Write ( indentString ) ;
859
+ sw . WriteLine ( $ " /// <summary>Initializes a new instance of the <see cref=\" { AttributeName } \" /> class.</summary>") ;
860
+ sw . Write ( indentString ) ;
861
+ sw . WriteLine ( " /// <param name=\" annotation\" >The annotation that was used in the native declaration.</param>" ) ;
862
+ sw . Write ( indentString ) ;
863
+ sw . WriteLine ( $ " public { AttributeName } (string annotation)") ;
864
+ sw . Write ( indentString ) ;
865
+ sw . WriteLine ( " {" ) ;
866
+ sw . Write ( indentString ) ;
867
+ sw . WriteLine ( " _annotation = annotation;" ) ;
868
+ sw . Write ( indentString ) ;
869
+ sw . WriteLine ( " }" ) ;
870
+ sw . WriteLine ( ) ;
871
+ sw . Write ( indentString ) ;
872
+ sw . WriteLine ( " /// <summary>Gets the annotation that was used in the native declaration.</summary>" ) ;
873
+ sw . Write ( indentString ) ;
874
+ sw . WriteLine ( " public string Annotation => _annotation;" ) ;
875
+ sw . Write ( indentString ) ;
876
+ sw . WriteLine ( '}' ) ;
877
+
878
+ if ( ! generator . Config . GenerateFileScopedNamespaces )
879
+ {
880
+ sw . WriteLine ( '}' ) ;
881
+ }
882
+
883
+ if ( ! leaveStreamOpen )
884
+ {
885
+ stream = null ;
886
+ }
887
+ }
888
+
798
889
static void GenerateSetsLastSystemErrorAttribute ( PInvokeGenerator generator , Stream ? stream , bool leaveStreamOpen )
799
890
{
800
891
var config = generator . Config ;
@@ -6724,6 +6815,13 @@ private void WithAttributes(NamedDecl namedDecl, bool onlySupportedOSPlatform =
6724
6815
break ;
6725
6816
}
6726
6817
6818
+ case CX_AttrKind_Annotate :
6819
+ {
6820
+ var annotationText = attr . Spelling ;
6821
+ outputBuilder . WriteCustomAttribute ( $ """ NativeAnnotation("{ annotationText } ")""" ) ;
6822
+ break ;
6823
+ }
6824
+
6727
6825
case CX_AttrKind_Format :
6728
6826
case CX_AttrKind_FormatArg :
6729
6827
case CX_AttrKind_MSNoVTable :
0 commit comments