|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis;
internal partial struct SymbolKey
{
private sealed class BuiltinOperatorSymbolKey : AbstractSymbolKey<IMethodSymbol>
{
public static readonly BuiltinOperatorSymbolKey Instance = new();
public sealed override void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.Name);
visitor.WriteSymbolKey(symbol.ReturnType);
visitor.WriteParameterTypesArray(symbol.Parameters);
}
protected sealed override SymbolKeyResolution Resolve(
SymbolKeyReader reader, IMethodSymbol? contextualSymbol, out string? failureReason)
{
var name = reader.ReadRequiredString();
var returnType = reader.ReadSymbolKey(contextualSymbol?.ReturnType, out var returnTypeFailureReason);
using var parameterTypes = reader.ReadSymbolKeyArray<IMethodSymbol, ITypeSymbol>(
contextualSymbol,
static (contextualSymbol, i) => SafeGet(contextualSymbol.Parameters, i)?.Type,
out var parameterTypesFailureReason);
if (returnTypeFailureReason != null)
{
failureReason = $"({nameof(BuiltinOperatorSymbolKey)} {nameof(returnType)} failed -> {returnTypeFailureReason})";
return default;
}
if (parameterTypesFailureReason != null)
{
failureReason = $"({nameof(BuiltinOperatorSymbolKey)} {nameof(parameterTypes)} failed -> {parameterTypesFailureReason})";
return default;
}
var returnTypeSymbol = (ITypeSymbol?)returnType.GetAnySymbol();
Contract.ThrowIfNull(returnTypeSymbol);
try
{
switch (parameterTypes.Count)
{
case 1:
failureReason = null;
var unaryOperator = reader.Compilation.CreateBuiltinOperator(name, returnTypeSymbol, parameterTypes[0]);
return new SymbolKeyResolution(unaryOperator);
case 2:
failureReason = null;
var binaryOperator = reader.Compilation.CreateBuiltinOperator(name, returnTypeSymbol, parameterTypes[0], parameterTypes[1]);
return new SymbolKeyResolution(binaryOperator);
default:
failureReason = $"({nameof(BuiltinOperatorSymbolKey)} {nameof(parameterTypes)} failed -> count was {parameterTypes.Count})";
return default;
}
}
catch (ArgumentException ex)
{
failureReason = $"({nameof(BuiltinOperatorSymbolKey)} failed -> {ex.Message})";
return default;
}
}
}
}
|