diff --git a/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs b/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs index b81065949..1c7db3227 100644 --- a/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs +++ b/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs @@ -374,6 +374,25 @@ namespace ICSharpCode.Decompiler.Tests.Output ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.ShowBody | ConversionFlags.PlaceReturnTypeAfterParameterList); Assert.That(ambience.ConvertSymbol(indexer), Is.EqualTo("public dynamic dynamic.this[int]")); } + + [Test] + public void ParameterizedProperty() + { + // A named property with parameters (VB.NET parameterized property); C# has no + // syntax for it, but signature surfaces show the parameter list in parentheses. + var property = new FakeProperty(compilation) { + Name = "Data", + ReturnType = compilation.FindType(KnownTypeCode.Int32), + DeclaringType = SpecialType.Dynamic, + Parameters = new IParameter[] { new DefaultParameter(compilation.FindType(KnownTypeCode.Int32), "index") }, + }; + + ambience.ConversionFlags = ILSpyMainTreeViewMemberFlags; + Assert.That(ambience.ConvertSymbol(property), Is.EqualTo("Data(int) : int")); + + ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.ShowBody | ConversionFlags.PlaceReturnTypeAfterParameterList); + Assert.That(ambience.ConvertSymbol(property), Is.EqualTo("public int dynamic.Data(int index)")); + } #endregion #region Test types diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs index 9268961b9..3b0d06743 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs @@ -148,6 +148,12 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor var subst = new TypeParameterSubstitution(extensionGroup.TypeParameters, null); parameters = extensionGroup.Marker.Specialize(subst).Parameters.Select(p => astBuilder.ConvertParameter(p)); } + else if (symbol is IProperty { SymbolKind: SymbolKind.Property } parameterizedProperty) + { + // C# property syntax has no parameter list, so the converted node carries + // none; parameterized properties take theirs from the symbol. + parameters = parameterizedProperty.Parameters.Select(p => astBuilder.ConvertParameter(p)); + } else { parameters = node.GetChildren(Slots.Parameter); @@ -256,6 +262,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor case SymbolKind.Operator: case SymbolKind.Constructor: case SymbolKind.Destructor: + case SymbolKind.Property when ((IProperty)e).Parameters.Count > 0: return (ConversionFlags & ConversionFlags.ShowParameterList) != 0; default: return false;