In summary, I had code like the following:
bool a = 3 > 5;
namespace System
{
public struct Int32
{
public static extern bool operator > (int a, int b);
}
public struct Boolean { }
}
but when I used GetDeclaredSymbol
on the declaration of the operator it gave me a different IMethodSymbol
than when I used it in the first line (bool a = 3 > 5;
).
I was looking for a method like GetDeclaredSymbol
but that would generate the same symbol that is used in the code as in the declaration.
GetDeclaredSymbol
-> SourceUserDefinedOperatorSymbol
GetSymbolInfo
-> SynthesizedIntrinsicOperatorSymbol
GetDeclaredSymbol
-> SynthesizedIntrinsicOperatorSymbol
GetSymbolInfo
-> SynthesizedIntrinsicOperatorSymbol
SourceUserDefinedOperatorSymbol
into SynthesizedIntrinsicOperatorSymbol
.Eg.
public static IMethodSymbol GetDeclaredSymbol (OperatorDeclarationSyntax ods)
{
IMethodSymbol opSym = model.GetDeclaredSymbol(ods) ?? throw E;
if (opSym is SourceUserDefinedOperatorSymbol)
{
// convert it to a SynthesizedIntrinsicOperatorSymbol instead
}
}
The solution I have gone with (unless I get a better answer) is to declare my operator declarations like the following:
public static bool operator > (int a, int b) => a > b;
and then to get the symbol for the operator I have the following function:
public static ISymbol GetDeclaredSymbol(CSharpSyntaxNode? declaration) =>
declaration is OperatorDeclarationSyntax { ExpressionBody: {} bod } } m &&
bod.DescendantNodes().OfType<BinaryExpressionSyntax>().SingleOrDefault() is {} bes ?
model.GetSymbolInfo(bes).Symbol! : model.GetDeclaredSymbol(declaration);