Skip to content

Commit c7dcfd9

Browse files
Timur KelmanTimur Kelman
Timur Kelman
authored and
Timur Kelman
committed
take parameter attributes into account in CreateOptionalRefArg
1 parent a69fa83 commit c7dcfd9

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

CodeConverter/CSharp/ExpressionNodeVisitor.cs

+47-1
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)