Skip to content

Commit df700fb

Browse files
Merge pull request #341 from icsharpcode/parameterized-properties
Parameterized properties
2 parents a0abfc8 + 22fb8a5 commit df700fb

4 files changed

Lines changed: 264 additions & 85 deletions

File tree

ICSharpCode.CodeConverter/CSharp/CommonConversions.cs

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.CodeAnalysis;
88
using Microsoft.CodeAnalysis.CSharp;
99
using Microsoft.CodeAnalysis.CSharp.Syntax;
10+
using Microsoft.CodeAnalysis.Operations;
1011
using Microsoft.CodeAnalysis.VisualBasic;
1112
using Microsoft.CodeAnalysis.VisualBasic.Syntax;
1213
using ArgumentListSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax.ArgumentListSyntax;
@@ -175,46 +176,46 @@ internal ExpressionSyntax GetLiteralExpression(object value, string textForUser
175176
{
176177
if (value is string valueTextForCompiler) {
177178
textForUser = GetQuotedStringTextForUser(textForUser, valueTextForCompiler);
178-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.StringLiteralExpression,
179+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.StringLiteralExpression,
179180
SyntaxFactory.Literal(textForUser, valueTextForCompiler));
180181
}
181182

182183
if (value == null)
183-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NullLiteralExpression);
184+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NullLiteralExpression);
184185
if (value is bool)
185-
return SyntaxFactory.LiteralExpression((bool)value ? Microsoft.CodeAnalysis.CSharp.SyntaxKind.TrueLiteralExpression : Microsoft.CodeAnalysis.CSharp.SyntaxKind.FalseLiteralExpression);
186+
return SyntaxFactory.LiteralExpression((bool)value ? CSSyntaxKind.TrueLiteralExpression : CSSyntaxKind.FalseLiteralExpression);
186187

187188
textForUser = textForUser != null ? ConvertNumericLiteralValueText(textForUser, value) : value.ToString();
188189

189190
if (value is byte)
190-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (byte)value));
191+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (byte)value));
191192
if (value is sbyte)
192-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (sbyte)value));
193+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (sbyte)value));
193194
if (value is short)
194-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (short)value));
195+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (short)value));
195196
if (value is ushort)
196-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (ushort)value));
197+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (ushort)value));
197198
if (value is int)
198-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (int)value));
199+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (int)value));
199200
if (value is uint)
200-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (uint)value));
201+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (uint)value));
201202
if (value is long)
202-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (long)value));
203+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (long)value));
203204
if (value is ulong)
204-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (ulong)value));
205+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (ulong)value));
205206

206207
if (value is float)
207-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (float)value));
208+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (float)value));
208209
if (value is double) {
209210
// Important to use value text, otherwise "10.0" gets coerced to and integer literal of 10 which can change semantics
210-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (double)value));
211+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (double)value));
211212
}
212213
if (value is decimal) {
213-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (decimal)value));
214+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(textForUser, (decimal)value));
214215
}
215216

216217
if (value is char)
217-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.CharacterLiteralExpression, SyntaxFactory.Literal((char)value));
218+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.CharacterLiteralExpression, SyntaxFactory.Literal((char)value));
218219

219220
if (value is DateTime dt) {
220221
var valueToOutput = dt.Date.Equals(dt) ? dt.ToString("yyyy-MM-dd") : dt.ToString("yyyy-MM-dd HH:mm:ss");
@@ -350,7 +351,7 @@ public static bool InMethodCalledInitializeComponent(SyntaxNode anyNodePossiblyW
350351

351352
private static SyntaxToken CsEscapedIdentifier(string text)
352353
{
353-
if (SyntaxFacts.GetKeywordKind(text) != Microsoft.CodeAnalysis.CSharp.SyntaxKind.None) text = "@" + text;
354+
if (SyntaxFacts.GetKeywordKind(text) != CSSyntaxKind.None) text = "@" + text;
354355
return SyntaxFactory.Identifier(text);
355356
}
356357

@@ -364,7 +365,7 @@ public SyntaxTokenList ConvertModifiers(SyntaxNode node, IEnumerable<SyntaxToken
364365
bool isPartial = declaredSymbol.IsPartialClassDefinition() || declaredSymbol.IsPartialMethodDefinition() || declaredSymbol.IsPartialMethodImplementation();
365366
bool implicitVisibility = contextsWithIdenticalDefaults.Contains(context) || isVariableOrConst || isConstructor;
366367
if (implicitVisibility && !isPartial) declaredAccessibility = Accessibility.NotApplicable;
367-
return SyntaxFactory.TokenList(ConvertModifiersCore(declaredAccessibility, modifiers, context).Where(t => CSharpExtensions.Kind(t) != Microsoft.CodeAnalysis.CSharp.SyntaxKind.None));
368+
return SyntaxFactory.TokenList(ConvertModifiersCore(declaredAccessibility, modifiers, context).Where(t => CSharpExtensions.Kind(t) != CSSyntaxKind.None));
368369
}
369370

370371
private SyntaxToken? ConvertModifier(SyntaxToken m, TokenContext context = TokenContext.Global)
@@ -375,7 +376,7 @@ public SyntaxTokenList ConvertModifiers(SyntaxNode node, IEnumerable<SyntaxToken
375376
return SyntaxFactory.Identifier("DateTime");
376377
}
377378
var token = vbSyntaxKind.ConvertToken(context);
378-
return token == Microsoft.CodeAnalysis.CSharp.SyntaxKind.None ? null : new SyntaxToken?(SyntaxFactory.Token(token));
379+
return token == CSSyntaxKind.None ? null : new SyntaxToken?(SyntaxFactory.Token(token));
379380
}
380381

381382
private IEnumerable<SyntaxToken> ConvertModifiersCore(Accessibility declaredAccessibility,
@@ -395,7 +396,7 @@ private IEnumerable<SyntaxToken> ConvertModifiersCore(Accessibility declaredAcce
395396
}
396397
if (context == TokenContext.MemberInModule &&
397398
!remainingModifiers.Any(a => VisualBasicExtensions.Kind(a) == SyntaxKind.ConstKeyword ))
398-
yield return SyntaxFactory.Token(Microsoft.CodeAnalysis.CSharp.SyntaxKind.StaticKeyword);
399+
yield return SyntaxFactory.Token(CSSyntaxKind.StaticKeyword);
399400
}
400401

401402
private IEnumerable<CSSyntaxKind> CsSyntaxAccessibilityKindForContext(Accessibility declaredAccessibility,
@@ -440,7 +441,7 @@ private bool IgnoreInContext(SyntaxToken m, TokenContext context)
440441

441442
public bool IsConversionOperator(SyntaxToken token)
442443
{
443-
bool isConvOp= token.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.ExplicitKeyword, Microsoft.CodeAnalysis.CSharp.SyntaxKind.ImplicitKeyword)
444+
bool isConvOp= token.IsKind(CSSyntaxKind.ExplicitKeyword, CSSyntaxKind.ImplicitKeyword)
444445
||token.IsKind(SyntaxKind.NarrowingKeyword, SyntaxKind.WideningKeyword);
445446
return isConvOp;
446447
}
@@ -482,11 +483,11 @@ private ExpressionSyntax IncreaseArrayUpperBoundExpression(VBSyntax.ExpressionSy
482483
{
483484
var constant = _semanticModel.GetConstantValue(expr);
484485
if (constant.HasValue && constant.Value is int)
485-
return SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal((int)constant.Value + 1));
486+
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal((int)constant.Value + 1));
486487

487488
return SyntaxFactory.BinaryExpression(
488-
Microsoft.CodeAnalysis.CSharp.SyntaxKind.SubtractExpression,
489-
(ExpressionSyntax)expr.Accept(_nodesVisitor), SyntaxFactory.Token(Microsoft.CodeAnalysis.CSharp.SyntaxKind.PlusToken), SyntaxFactory.LiteralExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(1)));
489+
CSSyntaxKind.SubtractExpression,
490+
(ExpressionSyntax)expr.Accept(_nodesVisitor), SyntaxFactory.Token(CSSyntaxKind.PlusToken), SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(1)));
490491
}
491492

492493
public static AttributeArgumentListSyntax CreateAttributeArgumentList(params AttributeArgumentSyntax[] attributeArgumentSyntaxs)
@@ -505,5 +506,25 @@ public static VariableDeclarationSyntax CreateVariableDeclarationAndAssignment(s
505506
SyntaxFactory.SingletonSeparatedList(variableDeclaratorSyntax));
506507
return variableDeclarationSyntax;
507508
}
509+
510+
public string GetParameterizedPropertyAccessMethod(IOperation operation, out ExpressionSyntax extraArg)
511+
{
512+
if (operation is IPropertyReferenceOperation pro && pro.Arguments.Any() &&
513+
!pro.Property.IsDefault()) {
514+
var isSetter = pro.Parent.Kind == OperationKind.SimpleAssignment && pro.Parent.Children.First() == pro;
515+
extraArg = isSetter
516+
? (ExpressionSyntax)_nodesVisitor.Visit(operation.Parent.Syntax.ChildNodes().ElementAt(1))
517+
: null;
518+
return isSetter ? pro.Property.SetMethod.Name : pro.Property.GetMethod.Name;
519+
}
520+
521+
extraArg = null;
522+
return null;
523+
}
524+
525+
public static bool IsDefaultIndexer(SyntaxNode node)
526+
{
527+
return node is PropertyStatementSyntax pss && pss.Modifiers.Any(m => SyntaxTokenExtensions.IsKind(m, Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.DefaultKeyword));
528+
}
508529
}
509530
}

ICSharpCode.CodeConverter/CSharp/MethodBodyVisitor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ public override SyntaxList<StatementSyntax> VisitExpressionStatement(VBSyntax.Ex
135135
public override SyntaxList<StatementSyntax> VisitAssignmentStatement(VBSyntax.AssignmentStatementSyntax node)
136136
{
137137
var lhs = (ExpressionSyntax)node.Left.Accept(_nodesVisitor);
138+
var lOperation = _semanticModel.GetOperation(node.Left);
139+
if (CommonConversions.GetParameterizedPropertyAccessMethod(lOperation, out var _) != null) return SingleStatement(lhs);
138140
var rhs = (ExpressionSyntax)node.Right.Accept(_nodesVisitor);
139141

140142
if (node.Left is VBSyntax.IdentifierNameSyntax id &&

0 commit comments

Comments
 (0)