@@ -55,6 +55,7 @@ private IEnumerable<MethodDeclarationSyntax> DeclareFriendlyOverloads(MethodDefi
5555        MethodSignature < TypeHandleInfo >  originalSignature  =  methodDefinition . DecodeSignature ( SignatureHandleProvider . Instance ,  null ) ; 
5656        var  parameters  =  externMethodDeclaration . ParameterList . Parameters . Select ( StripAttributes ) . ToList ( ) ; 
5757        var  lengthParamUsedBy  =  new  Dictionary < int ,  int > ( ) ; 
58+         var  parametersToRemove  =  new  List < int > ( ) ; 
5859        var  arguments  =  externMethodDeclaration . ParameterList . Parameters . Select ( p =>  Argument ( IdentifierName ( p . Identifier . Text ) ) . WithRefKindKeyword ( p . Modifiers . FirstOrDefault ( p =>  p . Kind ( )  is  SyntaxKind . RefKeyword  or SyntaxKind . OutKeyword  or SyntaxKind . InKeyword ) ) ) . ToList ( ) ; 
5960        TypeSyntax ?  externMethodReturnType  =  externMethodDeclaration . ReturnType . WithoutLeadingTrivia ( ) ; 
6061        var  fixedBlocks  =  new  List < VariableDeclarationSyntax > ( ) ; 
@@ -72,6 +73,8 @@ private IEnumerable<MethodDeclarationSyntax> DeclareFriendlyOverloads(MethodDefi
7273            } 
7374
7475            bool  isOptional  =  ( param . Attributes  &  ParameterAttributes . Optional )  ==  ParameterAttributes . Optional ; 
76+             bool  isReserved  =  this . FindInteropDecorativeAttribute ( param . GetCustomAttributes ( ) ,  "ReservedAttribute" )  is  not null ; 
77+             isOptional  |=  isReserved ;  // Per metadata decision made at https://github.com/microsoft/win32metadata/issues/1421#issuecomment-1372608090 
7578            bool  isIn  =  ( param . Attributes  &  ParameterAttributes . In )  ==  ParameterAttributes . In ; 
7679            bool  isConst  =  this . FindInteropDecorativeAttribute ( param . GetCustomAttributes ( ) ,  "ConstAttribute" )  is  not null ; 
7780            bool  isComOutPtr  =  this . FindInteropDecorativeAttribute ( param . GetCustomAttributes ( ) ,  "ComOutPtrAttribute" )  is  not null ; 
@@ -90,7 +93,14 @@ private IEnumerable<MethodDeclarationSyntax> DeclareFriendlyOverloads(MethodDefi
9093            bool  isManagedParameterType  =  this . IsManagedType ( parameterTypeInfo ) ; 
9194            IdentifierNameSyntax  origName  =  IdentifierName ( externParam . Identifier . ValueText ) ; 
9295
93-             if  ( isManagedParameterType  &&  ( externParam . Modifiers . Any ( SyntaxKind . OutKeyword )  ||  externParam . Modifiers . Any ( SyntaxKind . RefKeyword ) ) ) 
96+             if  ( isReserved  &&  ! isOut ) 
97+             { 
98+                 // Remove the parameter and supply the default value for the type to the extern method. 
99+                 arguments [ param . SequenceNumber  -  1 ]  =  Argument ( LiteralExpression ( SyntaxKind . DefaultLiteralExpression ) ) ; 
100+                 parametersToRemove . Add ( param . SequenceNumber  -  1 ) ; 
101+                 signatureChanged  =  true ; 
102+             } 
103+             else  if  ( isManagedParameterType  &&  ( externParam . Modifiers . Any ( SyntaxKind . OutKeyword )  ||  externParam . Modifiers . Any ( SyntaxKind . RefKeyword ) ) ) 
94104            { 
95105                bool  hasOut  =  externParam . Modifiers . Any ( SyntaxKind . OutKeyword ) ; 
96106                arguments [ param . SequenceNumber  -  1 ]  =  arguments [ param . SequenceNumber  -  1 ] . WithRefKindKeyword ( TokenWithSpace ( hasOut  ?  SyntaxKind . OutKeyword  :  SyntaxKind . RefKeyword ) ) ; 
@@ -487,15 +497,13 @@ private IEnumerable<MethodDeclarationSyntax> DeclareFriendlyOverloads(MethodDefi
487497
488498        if  ( signatureChanged ) 
489499        { 
490-             if  ( lengthParamUsedBy . Count  >  0 ) 
500+             // Remove in reverse order so as to not invalidate the indexes of elements to remove. 
501+             // Also take care to only remove each element once, even if it shows up multiple times in the collection. 
502+             SortedSet < int >  parameterIndexesToRemove  =  new ( lengthParamUsedBy . Keys ) ; 
503+             parameterIndexesToRemove . UnionWith ( parametersToRemove ) ; 
504+             foreach  ( int  indexToRemove  in  parameterIndexesToRemove . Reverse ( ) ) 
491505            { 
492-                 // Remove in reverse order so as to not invalidate the indexes of elements to remove. 
493-                 // Also take care to only remove each element once, even if it shows up multiple times in the collection. 
494-                 var  parameterIndexesToRemove  =  new  SortedSet < int > ( lengthParamUsedBy . Keys ) ; 
495-                 foreach  ( int  indexToRemove  in  parameterIndexesToRemove . Reverse ( ) ) 
496-                 { 
497-                     parameters . RemoveAt ( indexToRemove ) ; 
498-                 } 
506+                 parameters . RemoveAt ( indexToRemove ) ; 
499507            } 
500508
501509            TypeSyntax  docRefExternName  =  overloadOf  ==  FriendlyOverloadOf . InterfaceMethod 
0 commit comments