@@ -1818,8 +1818,54 @@ private ArgumentSyntax CreateExtraArgOrNull(IParameterSymbol p, bool requiresCom
18181818 private ArgumentSyntax CreateOptionalRefArg ( IParameterSymbol p , RefKind refKind )
18191819 {
18201820 string prefix = $ "arg{ p . Name } ";
1821- var local = _typeContext . PerScopeState . Hoist ( new AdditionalDeclaration ( prefix , CommonConversions . Literal ( p . ExplicitDefaultValue ) , CommonConversions . GetTypeSyntax ( p . Type ) ) ) ;
1821+ var type = CommonConversions . GetTypeSyntax ( p . Type ) ;
1822+ ExpressionSyntax initializer ;
1823+ if ( p . HasExplicitDefaultValue ) {
1824+ initializer = CommonConversions . Literal ( p . ExplicitDefaultValue ) ;
1825+ } else if ( HasOptionalAttribute ( p ) ) {
1826+ if ( TryGetDefaultParameterValueAttributeValue ( p , out var defaultValue ) ) {
1827+ initializer = CommonConversions . Literal ( defaultValue ) ;
1828+ } else {
1829+ initializer = SyntaxFactory . DefaultExpression ( type ) ;
1830+ }
1831+ } else {
1832+ //invalid VB.NET code
1833+ return null ;
1834+ }
1835+ var local = _typeContext . PerScopeState . Hoist ( new AdditionalDeclaration ( prefix , initializer , type ) ) ;
18221836 return ( ArgumentSyntax ) CommonConversions . CsSyntaxGenerator . Argument ( p . Name , refKind , local . IdentifierName ) ;
1837+
1838+ bool HasOptionalAttribute ( IParameterSymbol p )
1839+ {
1840+ var optionalAttribute = _semanticModel . Compilation . GetTypeByMetadataName ( "System.Runtime.InteropServices.OptionalAttribute" ) ;
1841+ if ( optionalAttribute == null ) {
1842+ return false ;
1843+ }
1844+
1845+ return p . GetAttributes ( ) . Any ( a => SymbolEqualityComparer . IncludeNullability . Equals ( a . AttributeClass , optionalAttribute ) ) ;
1846+ }
1847+
1848+ bool TryGetDefaultParameterValueAttributeValue ( IParameterSymbol p , out object defaultValue )
1849+ {
1850+ defaultValue = null ;
1851+
1852+ var defaultParameterValueAttribute = _semanticModel . Compilation . GetTypeByMetadataName ( "System.Runtime.InteropServices.DefaultParameterValueAttribute" ) ;
1853+ if ( defaultParameterValueAttribute == null ) {
1854+ return false ;
1855+ }
1856+
1857+ var attributeData = p . GetAttributes ( ) . FirstOrDefault ( a => SymbolEqualityComparer . IncludeNullability . Equals ( a . AttributeClass , defaultParameterValueAttribute ) ) ;
1858+ if ( attributeData == null ) {
1859+ return false ;
1860+ }
1861+
1862+ if ( attributeData . ConstructorArguments . Length == 0 ) {
1863+ return false ;
1864+ }
1865+
1866+ defaultValue = attributeData . ConstructorArguments . First ( ) . Value ;
1867+ return true ;
1868+ }
18231869 }
18241870
18251871 private RefConversion NeedsVariableForArgument ( VBasic . Syntax . ArgumentSyntax node , RefKind refKind )
0 commit comments