Skip to content

Commit ee2ab37

Browse files
committed
C#: Add support for compound assignment operators in the TryGetOperatorSymbol method.
1 parent bca51a9 commit ee2ab37

1 file changed

Lines changed: 54 additions & 98 deletions

File tree

Lines changed: 54 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Collections.Generic;
2+
using System.Collections.ObjectModel;
13
using System.Text.RegularExpressions;
24
using Microsoft.CodeAnalysis;
35

@@ -18,114 +20,68 @@ public static string GetName(this ISymbol symbol, bool useMetadataName = false)
1820
return symbol.CanBeReferencedByName ? name : name.Substring(symbol.Name.LastIndexOf('.') + 1);
1921
}
2022

23+
private static readonly ReadOnlyDictionary<string, string> methodToOperator = new(new Dictionary<string, string>
24+
{
25+
{ "op_LogicalNot", "!" },
26+
{ "op_BitwiseAnd", "&" },
27+
{ "op_Equality", "==" },
28+
{ "op_Inequality", "!=" },
29+
{ "op_UnaryPlus", "+" },
30+
{ "op_Addition", "+" },
31+
{ "op_UnaryNegation", "-" },
32+
{ "op_Subtraction", "-" },
33+
{ "op_Multiply", "*" },
34+
{ "op_Multiplication", "*" },
35+
{ "op_Division", "/" },
36+
{ "op_Modulus", "%" },
37+
{ "op_GreaterThan", ">" },
38+
{ "op_GreaterThanOrEqual", ">=" },
39+
{ "op_LessThan", "<" },
40+
{ "op_LessThanOrEqual", "<=" },
41+
{ "op_Decrement", "--" },
42+
{ "op_Increment", "++" },
43+
{ "op_Implicit", "implicit conversion" },
44+
{ "op_Explicit", "explicit conversion" },
45+
{ "op_OnesComplement", "~" },
46+
{ "op_RightShift", ">>" },
47+
{ "op_UnsignedRightShift", ">>>" },
48+
{ "op_LeftShift", "<<" },
49+
{ "op_BitwiseOr", "|" },
50+
{ "op_ExclusiveOr", "^" },
51+
{ "op_True", "true" },
52+
{ "op_False", "false" }
53+
});
54+
2155
/// <summary>
2256
/// Convert an operator method name in to a symbolic name.
2357
/// A return value indicates whether the conversion succeeded.
2458
/// </summary>
2559
public static bool TryGetOperatorSymbol(this ISymbol symbol, out string operatorName)
2660
{
27-
static bool TryGetOperatorSymbolFromName(string methodName, out string operatorName)
61+
var methodName = symbol.GetName(useMetadataName: false);
62+
63+
// Most common use-case.
64+
if (methodToOperator.TryGetValue(methodName, out var opName))
2865
{
29-
var success = true;
30-
switch (methodName)
31-
{
32-
case "op_LogicalNot":
33-
operatorName = "!";
34-
break;
35-
case "op_BitwiseAnd":
36-
operatorName = "&";
37-
break;
38-
case "op_Equality":
39-
operatorName = "==";
40-
break;
41-
case "op_Inequality":
42-
operatorName = "!=";
43-
break;
44-
case "op_UnaryPlus":
45-
case "op_Addition":
46-
operatorName = "+";
47-
break;
48-
case "op_UnaryNegation":
49-
case "op_Subtraction":
50-
operatorName = "-";
51-
break;
52-
case "op_Multiply":
53-
operatorName = "*";
54-
break;
55-
case "op_Division":
56-
operatorName = "/";
57-
break;
58-
case "op_Modulus":
59-
operatorName = "%";
60-
break;
61-
case "op_GreaterThan":
62-
operatorName = ">";
63-
break;
64-
case "op_GreaterThanOrEqual":
65-
operatorName = ">=";
66-
break;
67-
case "op_LessThan":
68-
operatorName = "<";
69-
break;
70-
case "op_LessThanOrEqual":
71-
operatorName = "<=";
72-
break;
73-
case "op_Decrement":
74-
operatorName = "--";
75-
break;
76-
case "op_Increment":
77-
operatorName = "++";
78-
break;
79-
case "op_Implicit":
80-
operatorName = "implicit conversion";
81-
break;
82-
case "op_Explicit":
83-
operatorName = "explicit conversion";
84-
break;
85-
case "op_OnesComplement":
86-
operatorName = "~";
87-
break;
88-
case "op_RightShift":
89-
operatorName = ">>";
90-
break;
91-
case "op_UnsignedRightShift":
92-
operatorName = ">>>";
93-
break;
94-
case "op_LeftShift":
95-
operatorName = "<<";
96-
break;
97-
case "op_BitwiseOr":
98-
operatorName = "|";
99-
break;
100-
case "op_ExclusiveOr":
101-
operatorName = "^";
102-
break;
103-
case "op_True":
104-
operatorName = "true";
105-
break;
106-
case "op_False":
107-
operatorName = "false";
108-
break;
109-
default:
110-
var match = CheckedRegex().Match(methodName);
111-
if (match.Success)
112-
{
113-
TryGetOperatorSymbolFromName($"op_{match.Groups[1]}", out var uncheckedName);
114-
operatorName = $"checked {uncheckedName}";
115-
break;
116-
}
117-
operatorName = methodName;
118-
success = false;
119-
break;
120-
}
121-
return success;
66+
operatorName = opName;
67+
return true;
12268
}
12369

124-
var methodName = symbol.GetName(useMetadataName: false);
125-
return TryGetOperatorSymbolFromName(methodName, out operatorName);
70+
// Attempt to parse using a regexp.
71+
var match = OperatorRegex().Match(methodName);
72+
if (match.Success && methodToOperator.TryGetValue($"op_{match.Groups[2]}", out var rawOperatorName))
73+
{
74+
var prefix = match.Groups[1].Success ? "checked " : "";
75+
var postfix = match.Groups[3].Success ? "=" : "";
76+
operatorName = $"{prefix}{rawOperatorName}{postfix}";
77+
return true;
78+
}
79+
80+
operatorName = methodName;
81+
return false;
12682
}
12783

128-
[GeneratedRegex("^op_Checked(.*)$")]
129-
private static partial Regex CheckedRegex();
84+
[GeneratedRegex("^op_(Checked)?(.*?)(Assignment)?$")]
85+
private static partial Regex OperatorRegex();
13086
}
13187
}

0 commit comments

Comments
 (0)