3

I was having trouble with operator resolution as seen in this question (take a look at this .NET fiddle).

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.

Actual

  • GetDeclaredSymbol -> SourceUserDefinedOperatorSymbol
  • GetSymbolInfo -> SynthesizedIntrinsicOperatorSymbol

Wanted (Expected)

  • GetDeclaredSymbol -> SynthesizedIntrinsicOperatorSymbol
  • GetSymbolInfo -> SynthesizedIntrinsicOperatorSymbol

Basically, I need a way to convert the 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
    }
}
trinalbadger587
  • 1,905
  • 1
  • 18
  • 36
  • But they are different: first one (`usedSymbol`) is of kind `BuitlInOperator`, and `declaredSymbols` is of kind `UserDefinedOperator`. In short - `bool a = 3 > 5;` does not use your operator - it uses built-in operator for ints. So one cannot be "converted" to the other. – Evk Sep 23 '21 at 12:18
  • I mean if I define a `UserDefinedOperator`, I would like something that will find the `BuiltInOperator` which matches the declaration. – trinalbadger587 Sep 23 '21 at 14:41
  • Still it's not clear to me what problem you are trying to solve. The operators are different. If you had a list of all bulit-in operators then you could in theory go over them one by one and check if any of them matches user defined operator you have (by comparing their signatures). – Evk Sep 23 '21 at 14:51
  • @Evk, Yes, I understand the operators are different but I have a `Dictionary>`. But when I declare `operator > (int, int)`, I want it to add the `BuiltinOperator` to the dictionary not the `UserDefinedOperator` so that when it is used in the code I can match it to the my method info class. – trinalbadger587 Sep 23 '21 at 15:16
  • @Evk, I tried to do the method you are saying but I couldn't figure out how to get a list of the built-in operators. That was the problem I encountered. – trinalbadger587 Sep 23 '21 at 15:17

1 Answers1

0

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);
trinalbadger587
  • 1,905
  • 1
  • 18
  • 36