|
// 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.
#nullable disable
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
{
/// <summary>
/// Internal cache of built-in operators.
/// Cache is compilation-specific because it uses compilation-specific SpecialTypes.
/// </summary>
internal class BuiltInOperators
{
private readonly CSharpCompilation _compilation;
//actual lazily-constructed caches of built-in operators.
private ImmutableArray<UnaryOperatorSignature>[] _builtInUnaryOperators;
private ImmutableArray<BinaryOperatorSignature>[][] _builtInOperators;
private SingleInitNullable<BinaryOperatorSignature> _builtInUtf8Concatenation;
internal BuiltInOperators(CSharpCompilation compilation)
{
_compilation = compilation;
}
// PERF: Use int instead of UnaryOperatorKind so the compiler can use array literal initialization.
// The most natural type choice, Enum arrays, are not blittable due to a CLR limitation.
private ImmutableArray<UnaryOperatorSignature> GetSignaturesFromUnaryOperatorKinds(int[] operatorKinds)
{
var builder = ArrayBuilder<UnaryOperatorSignature>.GetInstance();
foreach (var kind in operatorKinds)
{
builder.Add(GetSignature((UnaryOperatorKind)kind));
}
return builder.ToImmutableAndFree();
}
internal void GetSimpleBuiltInOperators(UnaryOperatorKind kind, ArrayBuilder<UnaryOperatorSignature> operators, bool skipNativeIntegerOperators)
{
if (_builtInUnaryOperators == null)
{
var allOperators = new ImmutableArray<UnaryOperatorSignature>[]
{
GetSignaturesFromUnaryOperatorKinds(new []
{
(int)UnaryOperatorKind.SBytePostfixIncrement,
(int)UnaryOperatorKind.BytePostfixIncrement,
(int)UnaryOperatorKind.ShortPostfixIncrement,
(int)UnaryOperatorKind.UShortPostfixIncrement,
(int)UnaryOperatorKind.IntPostfixIncrement,
(int)UnaryOperatorKind.UIntPostfixIncrement,
(int)UnaryOperatorKind.LongPostfixIncrement,
(int)UnaryOperatorKind.ULongPostfixIncrement,
(int)UnaryOperatorKind.NIntPostfixIncrement,
(int)UnaryOperatorKind.NUIntPostfixIncrement,
(int)UnaryOperatorKind.CharPostfixIncrement,
(int)UnaryOperatorKind.FloatPostfixIncrement,
(int)UnaryOperatorKind.DoublePostfixIncrement,
(int)UnaryOperatorKind.DecimalPostfixIncrement,
(int)UnaryOperatorKind.LiftedSBytePostfixIncrement,
(int)UnaryOperatorKind.LiftedBytePostfixIncrement,
(int)UnaryOperatorKind.LiftedShortPostfixIncrement,
(int)UnaryOperatorKind.LiftedUShortPostfixIncrement,
(int)UnaryOperatorKind.LiftedIntPostfixIncrement,
(int)UnaryOperatorKind.LiftedUIntPostfixIncrement,
(int)UnaryOperatorKind.LiftedLongPostfixIncrement,
(int)UnaryOperatorKind.LiftedULongPostfixIncrement,
(int)UnaryOperatorKind.LiftedNIntPostfixIncrement,
(int)UnaryOperatorKind.LiftedNUIntPostfixIncrement,
(int)UnaryOperatorKind.LiftedCharPostfixIncrement,
(int)UnaryOperatorKind.LiftedFloatPostfixIncrement,
(int)UnaryOperatorKind.LiftedDoublePostfixIncrement,
(int)UnaryOperatorKind.LiftedDecimalPostfixIncrement,
}),
GetSignaturesFromUnaryOperatorKinds(new []
{
(int)UnaryOperatorKind.SBytePostfixDecrement,
(int)UnaryOperatorKind.BytePostfixDecrement,
(int)UnaryOperatorKind.ShortPostfixDecrement,
(int)UnaryOperatorKind.UShortPostfixDecrement,
(int)UnaryOperatorKind.IntPostfixDecrement,
(int)UnaryOperatorKind.UIntPostfixDecrement,
(int)UnaryOperatorKind.LongPostfixDecrement,
(int)UnaryOperatorKind.ULongPostfixDecrement,
(int)UnaryOperatorKind.NIntPostfixDecrement,
(int)UnaryOperatorKind.NUIntPostfixDecrement,
(int)UnaryOperatorKind.CharPostfixDecrement,
(int)UnaryOperatorKind.FloatPostfixDecrement,
(int)UnaryOperatorKind.DoublePostfixDecrement,
(int)UnaryOperatorKind.DecimalPostfixDecrement,
(int)UnaryOperatorKind.LiftedSBytePostfixDecrement,
(int)UnaryOperatorKind.LiftedBytePostfixDecrement,
(int)UnaryOperatorKind.LiftedShortPostfixDecrement,
(int)UnaryOperatorKind.LiftedUShortPostfixDecrement,
(int)UnaryOperatorKind.LiftedIntPostfixDecrement,
(int)UnaryOperatorKind.LiftedUIntPostfixDecrement,
(int)UnaryOperatorKind.LiftedLongPostfixDecrement,
(int)UnaryOperatorKind.LiftedULongPostfixDecrement,
(int)UnaryOperatorKind.LiftedNIntPostfixDecrement,
(int)UnaryOperatorKind.LiftedNUIntPostfixDecrement,
(int)UnaryOperatorKind.LiftedCharPostfixDecrement,
(int)UnaryOperatorKind.LiftedFloatPostfixDecrement,
(int)UnaryOperatorKind.LiftedDoublePostfixDecrement,
(int)UnaryOperatorKind.LiftedDecimalPostfixDecrement,
}),
GetSignaturesFromUnaryOperatorKinds(new []
{
(int)UnaryOperatorKind.SBytePrefixIncrement,
(int)UnaryOperatorKind.BytePrefixIncrement,
(int)UnaryOperatorKind.ShortPrefixIncrement,
(int)UnaryOperatorKind.UShortPrefixIncrement,
(int)UnaryOperatorKind.IntPrefixIncrement,
(int)UnaryOperatorKind.UIntPrefixIncrement,
(int)UnaryOperatorKind.LongPrefixIncrement,
(int)UnaryOperatorKind.ULongPrefixIncrement,
(int)UnaryOperatorKind.NIntPrefixIncrement,
(int)UnaryOperatorKind.NUIntPrefixIncrement,
(int)UnaryOperatorKind.CharPrefixIncrement,
(int)UnaryOperatorKind.FloatPrefixIncrement,
(int)UnaryOperatorKind.DoublePrefixIncrement,
(int)UnaryOperatorKind.DecimalPrefixIncrement,
(int)UnaryOperatorKind.LiftedSBytePrefixIncrement,
(int)UnaryOperatorKind.LiftedBytePrefixIncrement,
(int)UnaryOperatorKind.LiftedShortPrefixIncrement,
(int)UnaryOperatorKind.LiftedUShortPrefixIncrement,
(int)UnaryOperatorKind.LiftedIntPrefixIncrement,
(int)UnaryOperatorKind.LiftedUIntPrefixIncrement,
(int)UnaryOperatorKind.LiftedLongPrefixIncrement,
(int)UnaryOperatorKind.LiftedULongPrefixIncrement,
(int)UnaryOperatorKind.LiftedNIntPrefixIncrement,
(int)UnaryOperatorKind.LiftedNUIntPrefixIncrement,
(int)UnaryOperatorKind.LiftedCharPrefixIncrement,
(int)UnaryOperatorKind.LiftedFloatPrefixIncrement,
(int)UnaryOperatorKind.LiftedDoublePrefixIncrement,
(int)UnaryOperatorKind.LiftedDecimalPrefixIncrement,
}),
GetSignaturesFromUnaryOperatorKinds(new []
{
(int)UnaryOperatorKind.SBytePrefixDecrement,
(int)UnaryOperatorKind.BytePrefixDecrement,
(int)UnaryOperatorKind.ShortPrefixDecrement,
(int)UnaryOperatorKind.UShortPrefixDecrement,
(int)UnaryOperatorKind.IntPrefixDecrement,
(int)UnaryOperatorKind.UIntPrefixDecrement,
(int)UnaryOperatorKind.NIntPrefixDecrement,
(int)UnaryOperatorKind.NUIntPrefixDecrement,
(int)UnaryOperatorKind.LongPrefixDecrement,
(int)UnaryOperatorKind.ULongPrefixDecrement,
(int)UnaryOperatorKind.CharPrefixDecrement,
(int)UnaryOperatorKind.FloatPrefixDecrement,
(int)UnaryOperatorKind.DoublePrefixDecrement,
(int)UnaryOperatorKind.DecimalPrefixDecrement,
(int)UnaryOperatorKind.LiftedSBytePrefixDecrement,
(int)UnaryOperatorKind.LiftedBytePrefixDecrement,
(int)UnaryOperatorKind.LiftedShortPrefixDecrement,
(int)UnaryOperatorKind.LiftedUShortPrefixDecrement,
(int)UnaryOperatorKind.LiftedIntPrefixDecrement,
(int)UnaryOperatorKind.LiftedUIntPrefixDecrement,
(int)UnaryOperatorKind.LiftedLongPrefixDecrement,
(int)UnaryOperatorKind.LiftedULongPrefixDecrement,
(int)UnaryOperatorKind.LiftedNIntPrefixDecrement,
(int)UnaryOperatorKind.LiftedNUIntPrefixDecrement,
(int)UnaryOperatorKind.LiftedCharPrefixDecrement,
(int)UnaryOperatorKind.LiftedFloatPrefixDecrement,
(int)UnaryOperatorKind.LiftedDoublePrefixDecrement,
(int)UnaryOperatorKind.LiftedDecimalPrefixDecrement,
}),
GetSignaturesFromUnaryOperatorKinds(new []
{
(int)UnaryOperatorKind.IntUnaryPlus,
(int)UnaryOperatorKind.UIntUnaryPlus,
(int)UnaryOperatorKind.LongUnaryPlus,
(int)UnaryOperatorKind.ULongUnaryPlus,
(int)UnaryOperatorKind.NIntUnaryPlus,
(int)UnaryOperatorKind.NUIntUnaryPlus,
(int)UnaryOperatorKind.FloatUnaryPlus,
(int)UnaryOperatorKind.DoubleUnaryPlus,
(int)UnaryOperatorKind.DecimalUnaryPlus,
(int)UnaryOperatorKind.LiftedIntUnaryPlus,
(int)UnaryOperatorKind.LiftedUIntUnaryPlus,
(int)UnaryOperatorKind.LiftedLongUnaryPlus,
(int)UnaryOperatorKind.LiftedULongUnaryPlus,
(int)UnaryOperatorKind.LiftedNIntUnaryPlus,
(int)UnaryOperatorKind.LiftedNUIntUnaryPlus,
(int)UnaryOperatorKind.LiftedFloatUnaryPlus,
(int)UnaryOperatorKind.LiftedDoubleUnaryPlus,
(int)UnaryOperatorKind.LiftedDecimalUnaryPlus,
}),
GetSignaturesFromUnaryOperatorKinds(new []
{
(int)UnaryOperatorKind.IntUnaryMinus,
(int)UnaryOperatorKind.LongUnaryMinus,
(int)UnaryOperatorKind.NIntUnaryMinus,
(int)UnaryOperatorKind.FloatUnaryMinus,
(int)UnaryOperatorKind.DoubleUnaryMinus,
(int)UnaryOperatorKind.DecimalUnaryMinus,
(int)UnaryOperatorKind.LiftedIntUnaryMinus,
(int)UnaryOperatorKind.LiftedLongUnaryMinus,
(int)UnaryOperatorKind.LiftedNIntUnaryMinus,
(int)UnaryOperatorKind.LiftedFloatUnaryMinus,
(int)UnaryOperatorKind.LiftedDoubleUnaryMinus,
(int)UnaryOperatorKind.LiftedDecimalUnaryMinus,
}),
GetSignaturesFromUnaryOperatorKinds(new []
{
(int)UnaryOperatorKind.BoolLogicalNegation,
(int)UnaryOperatorKind.LiftedBoolLogicalNegation,
}),
GetSignaturesFromUnaryOperatorKinds(new []
{
(int)UnaryOperatorKind.IntBitwiseComplement,
(int)UnaryOperatorKind.UIntBitwiseComplement,
(int)UnaryOperatorKind.LongBitwiseComplement,
(int)UnaryOperatorKind.ULongBitwiseComplement,
(int)UnaryOperatorKind.NIntBitwiseComplement,
(int)UnaryOperatorKind.NUIntBitwiseComplement,
(int)UnaryOperatorKind.LiftedIntBitwiseComplement,
(int)UnaryOperatorKind.LiftedUIntBitwiseComplement,
(int)UnaryOperatorKind.LiftedLongBitwiseComplement,
(int)UnaryOperatorKind.LiftedULongBitwiseComplement,
(int)UnaryOperatorKind.LiftedNIntBitwiseComplement,
(int)UnaryOperatorKind.LiftedNUIntBitwiseComplement,
}),
// No built-in operator true or operator false
ImmutableArray<UnaryOperatorSignature>.Empty,
ImmutableArray<UnaryOperatorSignature>.Empty,
};
Interlocked.CompareExchange(ref _builtInUnaryOperators, allOperators, null);
}
foreach (var op in _builtInUnaryOperators[kind.OperatorIndex()])
{
if (skipNativeIntegerOperators)
{
switch (op.Kind.OperandTypes())
{
case UnaryOperatorKind.NInt:
case UnaryOperatorKind.NUInt:
continue;
}
}
operators.Add(op);
}
}
internal UnaryOperatorSignature GetSignature(UnaryOperatorKind kind)
{
TypeSymbol opType;
switch (kind.OperandTypes())
{
case UnaryOperatorKind.SByte: opType = _compilation.GetSpecialType(SpecialType.System_SByte); break;
case UnaryOperatorKind.Byte: opType = _compilation.GetSpecialType(SpecialType.System_Byte); break;
case UnaryOperatorKind.Short: opType = _compilation.GetSpecialType(SpecialType.System_Int16); break;
case UnaryOperatorKind.UShort: opType = _compilation.GetSpecialType(SpecialType.System_UInt16); break;
case UnaryOperatorKind.Int: opType = _compilation.GetSpecialType(SpecialType.System_Int32); break;
case UnaryOperatorKind.UInt: opType = _compilation.GetSpecialType(SpecialType.System_UInt32); break;
case UnaryOperatorKind.Long: opType = _compilation.GetSpecialType(SpecialType.System_Int64); break;
case UnaryOperatorKind.ULong: opType = _compilation.GetSpecialType(SpecialType.System_UInt64); break;
case UnaryOperatorKind.NInt: opType = _compilation.CreateNativeIntegerTypeSymbol(signed: true); break;
case UnaryOperatorKind.NUInt: opType = _compilation.CreateNativeIntegerTypeSymbol(signed: false); break;
case UnaryOperatorKind.Char: opType = _compilation.GetSpecialType(SpecialType.System_Char); break;
case UnaryOperatorKind.Float: opType = _compilation.GetSpecialType(SpecialType.System_Single); break;
case UnaryOperatorKind.Double: opType = _compilation.GetSpecialType(SpecialType.System_Double); break;
case UnaryOperatorKind.Decimal: opType = _compilation.GetSpecialType(SpecialType.System_Decimal); break;
case UnaryOperatorKind.Bool: opType = _compilation.GetSpecialType(SpecialType.System_Boolean); break;
default: throw ExceptionUtilities.UnexpectedValue(kind.OperandTypes());
}
if (kind.IsLifted())
{
opType = _compilation.GetOrCreateNullableType(opType);
}
return new UnaryOperatorSignature(kind, opType, opType);
}
// PERF: Use int instead of BinaryOperatorKind so the compiler can use array literal initialization.
// The most natural type choice, Enum arrays, are not blittable due to a CLR limitation.
private ImmutableArray<BinaryOperatorSignature> GetSignaturesFromBinaryOperatorKinds(int[] operatorKinds)
{
var builder = ArrayBuilder<BinaryOperatorSignature>.GetInstance();
foreach (var kind in operatorKinds)
{
builder.Add(GetSignature((BinaryOperatorKind)kind));
}
return builder.ToImmutableAndFree();
}
internal void GetSimpleBuiltInOperators(BinaryOperatorKind kind, ArrayBuilder<BinaryOperatorSignature> operators, bool skipNativeIntegerOperators)
{
if (_builtInOperators == null)
{
var logicalOperators = new ImmutableArray<BinaryOperatorSignature>[]
{
ImmutableArray<BinaryOperatorSignature>.Empty, //multiplication
ImmutableArray<BinaryOperatorSignature>.Empty, //addition
ImmutableArray<BinaryOperatorSignature>.Empty, //subtraction
ImmutableArray<BinaryOperatorSignature>.Empty, //division
ImmutableArray<BinaryOperatorSignature>.Empty, //remainder
ImmutableArray<BinaryOperatorSignature>.Empty, //left shift
ImmutableArray<BinaryOperatorSignature>.Empty, //right shift
ImmutableArray<BinaryOperatorSignature>.Empty, //equal
ImmutableArray<BinaryOperatorSignature>.Empty, //not equal
ImmutableArray<BinaryOperatorSignature>.Empty, //greater than
ImmutableArray<BinaryOperatorSignature>.Empty, //less than
ImmutableArray<BinaryOperatorSignature>.Empty, //greater than or equal
ImmutableArray<BinaryOperatorSignature>.Empty, //less than or equal
ImmutableArray.Create<BinaryOperatorSignature>(GetSignature(BinaryOperatorKind.LogicalBoolAnd)), //and
ImmutableArray<BinaryOperatorSignature>.Empty, //xor
ImmutableArray.Create<BinaryOperatorSignature>(GetSignature(BinaryOperatorKind.LogicalBoolOr)), //or
ImmutableArray<BinaryOperatorSignature>.Empty, //unsigned right shift
};
var nonLogicalOperators = new ImmutableArray<BinaryOperatorSignature>[]
{
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntMultiplication,
(int)BinaryOperatorKind.UIntMultiplication,
(int)BinaryOperatorKind.LongMultiplication,
(int)BinaryOperatorKind.ULongMultiplication,
(int)BinaryOperatorKind.NIntMultiplication,
(int)BinaryOperatorKind.NUIntMultiplication,
(int)BinaryOperatorKind.FloatMultiplication,
(int)BinaryOperatorKind.DoubleMultiplication,
(int)BinaryOperatorKind.DecimalMultiplication,
(int)BinaryOperatorKind.LiftedIntMultiplication,
(int)BinaryOperatorKind.LiftedUIntMultiplication,
(int)BinaryOperatorKind.LiftedLongMultiplication,
(int)BinaryOperatorKind.LiftedULongMultiplication,
(int)BinaryOperatorKind.LiftedNIntMultiplication,
(int)BinaryOperatorKind.LiftedNUIntMultiplication,
(int)BinaryOperatorKind.LiftedFloatMultiplication,
(int)BinaryOperatorKind.LiftedDoubleMultiplication,
(int)BinaryOperatorKind.LiftedDecimalMultiplication,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntAddition,
(int)BinaryOperatorKind.UIntAddition,
(int)BinaryOperatorKind.LongAddition,
(int)BinaryOperatorKind.ULongAddition,
(int)BinaryOperatorKind.NIntAddition,
(int)BinaryOperatorKind.NUIntAddition,
(int)BinaryOperatorKind.FloatAddition,
(int)BinaryOperatorKind.DoubleAddition,
(int)BinaryOperatorKind.DecimalAddition,
(int)BinaryOperatorKind.LiftedIntAddition,
(int)BinaryOperatorKind.LiftedUIntAddition,
(int)BinaryOperatorKind.LiftedLongAddition,
(int)BinaryOperatorKind.LiftedULongAddition,
(int)BinaryOperatorKind.LiftedNIntAddition,
(int)BinaryOperatorKind.LiftedNUIntAddition,
(int)BinaryOperatorKind.LiftedFloatAddition,
(int)BinaryOperatorKind.LiftedDoubleAddition,
(int)BinaryOperatorKind.LiftedDecimalAddition,
(int)BinaryOperatorKind.StringConcatenation,
(int)BinaryOperatorKind.StringAndObjectConcatenation,
(int)BinaryOperatorKind.ObjectAndStringConcatenation,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntSubtraction,
(int)BinaryOperatorKind.UIntSubtraction,
(int)BinaryOperatorKind.LongSubtraction,
(int)BinaryOperatorKind.ULongSubtraction,
(int)BinaryOperatorKind.NIntSubtraction,
(int)BinaryOperatorKind.NUIntSubtraction,
(int)BinaryOperatorKind.FloatSubtraction,
(int)BinaryOperatorKind.DoubleSubtraction,
(int)BinaryOperatorKind.DecimalSubtraction,
(int)BinaryOperatorKind.LiftedIntSubtraction,
(int)BinaryOperatorKind.LiftedUIntSubtraction,
(int)BinaryOperatorKind.LiftedLongSubtraction,
(int)BinaryOperatorKind.LiftedULongSubtraction,
(int)BinaryOperatorKind.LiftedNIntSubtraction,
(int)BinaryOperatorKind.LiftedNUIntSubtraction,
(int)BinaryOperatorKind.LiftedFloatSubtraction,
(int)BinaryOperatorKind.LiftedDoubleSubtraction,
(int)BinaryOperatorKind.LiftedDecimalSubtraction,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntDivision,
(int)BinaryOperatorKind.UIntDivision,
(int)BinaryOperatorKind.LongDivision,
(int)BinaryOperatorKind.ULongDivision,
(int)BinaryOperatorKind.NIntDivision,
(int)BinaryOperatorKind.NUIntDivision,
(int)BinaryOperatorKind.FloatDivision,
(int)BinaryOperatorKind.DoubleDivision,
(int)BinaryOperatorKind.DecimalDivision,
(int)BinaryOperatorKind.LiftedIntDivision,
(int)BinaryOperatorKind.LiftedUIntDivision,
(int)BinaryOperatorKind.LiftedLongDivision,
(int)BinaryOperatorKind.LiftedULongDivision,
(int)BinaryOperatorKind.LiftedNIntDivision,
(int)BinaryOperatorKind.LiftedNUIntDivision,
(int)BinaryOperatorKind.LiftedFloatDivision,
(int)BinaryOperatorKind.LiftedDoubleDivision,
(int)BinaryOperatorKind.LiftedDecimalDivision,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntRemainder,
(int)BinaryOperatorKind.UIntRemainder,
(int)BinaryOperatorKind.LongRemainder,
(int)BinaryOperatorKind.ULongRemainder,
(int)BinaryOperatorKind.NIntRemainder,
(int)BinaryOperatorKind.NUIntRemainder,
(int)BinaryOperatorKind.FloatRemainder,
(int)BinaryOperatorKind.DoubleRemainder,
(int)BinaryOperatorKind.DecimalRemainder,
(int)BinaryOperatorKind.LiftedIntRemainder,
(int)BinaryOperatorKind.LiftedUIntRemainder,
(int)BinaryOperatorKind.LiftedLongRemainder,
(int)BinaryOperatorKind.LiftedULongRemainder,
(int)BinaryOperatorKind.LiftedNIntRemainder,
(int)BinaryOperatorKind.LiftedNUIntRemainder,
(int)BinaryOperatorKind.LiftedFloatRemainder,
(int)BinaryOperatorKind.LiftedDoubleRemainder,
(int)BinaryOperatorKind.LiftedDecimalRemainder,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntLeftShift,
(int)BinaryOperatorKind.UIntLeftShift,
(int)BinaryOperatorKind.LongLeftShift,
(int)BinaryOperatorKind.ULongLeftShift,
(int)BinaryOperatorKind.NIntLeftShift,
(int)BinaryOperatorKind.NUIntLeftShift,
(int)BinaryOperatorKind.LiftedIntLeftShift,
(int)BinaryOperatorKind.LiftedUIntLeftShift,
(int)BinaryOperatorKind.LiftedLongLeftShift,
(int)BinaryOperatorKind.LiftedULongLeftShift,
(int)BinaryOperatorKind.LiftedNIntLeftShift,
(int)BinaryOperatorKind.LiftedNUIntLeftShift,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntRightShift,
(int)BinaryOperatorKind.UIntRightShift,
(int)BinaryOperatorKind.LongRightShift,
(int)BinaryOperatorKind.ULongRightShift,
(int)BinaryOperatorKind.NIntRightShift,
(int)BinaryOperatorKind.NUIntRightShift,
(int)BinaryOperatorKind.LiftedIntRightShift,
(int)BinaryOperatorKind.LiftedUIntRightShift,
(int)BinaryOperatorKind.LiftedLongRightShift,
(int)BinaryOperatorKind.LiftedULongRightShift,
(int)BinaryOperatorKind.LiftedNIntRightShift,
(int)BinaryOperatorKind.LiftedNUIntRightShift,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntEqual,
(int)BinaryOperatorKind.UIntEqual,
(int)BinaryOperatorKind.LongEqual,
(int)BinaryOperatorKind.ULongEqual,
(int)BinaryOperatorKind.NIntEqual,
(int)BinaryOperatorKind.NUIntEqual,
(int)BinaryOperatorKind.FloatEqual,
(int)BinaryOperatorKind.DoubleEqual,
(int)BinaryOperatorKind.DecimalEqual,
(int)BinaryOperatorKind.BoolEqual,
(int)BinaryOperatorKind.LiftedIntEqual,
(int)BinaryOperatorKind.LiftedUIntEqual,
(int)BinaryOperatorKind.LiftedLongEqual,
(int)BinaryOperatorKind.LiftedULongEqual,
(int)BinaryOperatorKind.LiftedNIntEqual,
(int)BinaryOperatorKind.LiftedNUIntEqual,
(int)BinaryOperatorKind.LiftedFloatEqual,
(int)BinaryOperatorKind.LiftedDoubleEqual,
(int)BinaryOperatorKind.LiftedDecimalEqual,
(int)BinaryOperatorKind.LiftedBoolEqual,
(int)BinaryOperatorKind.ObjectEqual,
(int)BinaryOperatorKind.StringEqual,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntNotEqual,
(int)BinaryOperatorKind.UIntNotEqual,
(int)BinaryOperatorKind.LongNotEqual,
(int)BinaryOperatorKind.ULongNotEqual,
(int)BinaryOperatorKind.NIntNotEqual,
(int)BinaryOperatorKind.NUIntNotEqual,
(int)BinaryOperatorKind.FloatNotEqual,
(int)BinaryOperatorKind.DoubleNotEqual,
(int)BinaryOperatorKind.DecimalNotEqual,
(int)BinaryOperatorKind.BoolNotEqual,
(int)BinaryOperatorKind.LiftedIntNotEqual,
(int)BinaryOperatorKind.LiftedUIntNotEqual,
(int)BinaryOperatorKind.LiftedLongNotEqual,
(int)BinaryOperatorKind.LiftedULongNotEqual,
(int)BinaryOperatorKind.LiftedNIntNotEqual,
(int)BinaryOperatorKind.LiftedNUIntNotEqual,
(int)BinaryOperatorKind.LiftedFloatNotEqual,
(int)BinaryOperatorKind.LiftedDoubleNotEqual,
(int)BinaryOperatorKind.LiftedDecimalNotEqual,
(int)BinaryOperatorKind.LiftedBoolNotEqual,
(int)BinaryOperatorKind.ObjectNotEqual,
(int)BinaryOperatorKind.StringNotEqual,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntGreaterThan,
(int)BinaryOperatorKind.UIntGreaterThan,
(int)BinaryOperatorKind.LongGreaterThan,
(int)BinaryOperatorKind.ULongGreaterThan,
(int)BinaryOperatorKind.NIntGreaterThan,
(int)BinaryOperatorKind.NUIntGreaterThan,
(int)BinaryOperatorKind.FloatGreaterThan,
(int)BinaryOperatorKind.DoubleGreaterThan,
(int)BinaryOperatorKind.DecimalGreaterThan,
(int)BinaryOperatorKind.LiftedIntGreaterThan,
(int)BinaryOperatorKind.LiftedUIntGreaterThan,
(int)BinaryOperatorKind.LiftedLongGreaterThan,
(int)BinaryOperatorKind.LiftedULongGreaterThan,
(int)BinaryOperatorKind.LiftedNIntGreaterThan,
(int)BinaryOperatorKind.LiftedNUIntGreaterThan,
(int)BinaryOperatorKind.LiftedFloatGreaterThan,
(int)BinaryOperatorKind.LiftedDoubleGreaterThan,
(int)BinaryOperatorKind.LiftedDecimalGreaterThan,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntLessThan,
(int)BinaryOperatorKind.UIntLessThan,
(int)BinaryOperatorKind.LongLessThan,
(int)BinaryOperatorKind.ULongLessThan,
(int)BinaryOperatorKind.NIntLessThan,
(int)BinaryOperatorKind.NUIntLessThan,
(int)BinaryOperatorKind.FloatLessThan,
(int)BinaryOperatorKind.DoubleLessThan,
(int)BinaryOperatorKind.DecimalLessThan,
(int)BinaryOperatorKind.LiftedIntLessThan,
(int)BinaryOperatorKind.LiftedUIntLessThan,
(int)BinaryOperatorKind.LiftedLongLessThan,
(int)BinaryOperatorKind.LiftedULongLessThan,
(int)BinaryOperatorKind.LiftedNIntLessThan,
(int)BinaryOperatorKind.LiftedNUIntLessThan,
(int)BinaryOperatorKind.LiftedFloatLessThan,
(int)BinaryOperatorKind.LiftedDoubleLessThan,
(int)BinaryOperatorKind.LiftedDecimalLessThan,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntGreaterThanOrEqual,
(int)BinaryOperatorKind.UIntGreaterThanOrEqual,
(int)BinaryOperatorKind.LongGreaterThanOrEqual,
(int)BinaryOperatorKind.ULongGreaterThanOrEqual,
(int)BinaryOperatorKind.NIntGreaterThanOrEqual,
(int)BinaryOperatorKind.NUIntGreaterThanOrEqual,
(int)BinaryOperatorKind.FloatGreaterThanOrEqual,
(int)BinaryOperatorKind.DoubleGreaterThanOrEqual,
(int)BinaryOperatorKind.DecimalGreaterThanOrEqual,
(int)BinaryOperatorKind.LiftedIntGreaterThanOrEqual,
(int)BinaryOperatorKind.LiftedUIntGreaterThanOrEqual,
(int)BinaryOperatorKind.LiftedLongGreaterThanOrEqual,
(int)BinaryOperatorKind.LiftedULongGreaterThanOrEqual,
(int)BinaryOperatorKind.LiftedNIntGreaterThanOrEqual,
(int)BinaryOperatorKind.LiftedNUIntGreaterThanOrEqual,
(int)BinaryOperatorKind.LiftedFloatGreaterThanOrEqual,
(int)BinaryOperatorKind.LiftedDoubleGreaterThanOrEqual,
(int)BinaryOperatorKind.LiftedDecimalGreaterThanOrEqual,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntLessThanOrEqual,
(int)BinaryOperatorKind.UIntLessThanOrEqual,
(int)BinaryOperatorKind.LongLessThanOrEqual,
(int)BinaryOperatorKind.ULongLessThanOrEqual,
(int)BinaryOperatorKind.NIntLessThanOrEqual,
(int)BinaryOperatorKind.NUIntLessThanOrEqual,
(int)BinaryOperatorKind.FloatLessThanOrEqual,
(int)BinaryOperatorKind.DoubleLessThanOrEqual,
(int)BinaryOperatorKind.DecimalLessThanOrEqual,
(int)BinaryOperatorKind.LiftedIntLessThanOrEqual,
(int)BinaryOperatorKind.LiftedUIntLessThanOrEqual,
(int)BinaryOperatorKind.LiftedLongLessThanOrEqual,
(int)BinaryOperatorKind.LiftedULongLessThanOrEqual,
(int)BinaryOperatorKind.LiftedNIntLessThanOrEqual,
(int)BinaryOperatorKind.LiftedNUIntLessThanOrEqual,
(int)BinaryOperatorKind.LiftedFloatLessThanOrEqual,
(int)BinaryOperatorKind.LiftedDoubleLessThanOrEqual,
(int)BinaryOperatorKind.LiftedDecimalLessThanOrEqual,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntAnd,
(int)BinaryOperatorKind.UIntAnd,
(int)BinaryOperatorKind.LongAnd,
(int)BinaryOperatorKind.ULongAnd,
(int)BinaryOperatorKind.NIntAnd,
(int)BinaryOperatorKind.NUIntAnd,
(int)BinaryOperatorKind.BoolAnd,
(int)BinaryOperatorKind.LiftedIntAnd,
(int)BinaryOperatorKind.LiftedUIntAnd,
(int)BinaryOperatorKind.LiftedLongAnd,
(int)BinaryOperatorKind.LiftedULongAnd,
(int)BinaryOperatorKind.LiftedNIntAnd,
(int)BinaryOperatorKind.LiftedNUIntAnd,
(int)BinaryOperatorKind.LiftedBoolAnd,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntXor,
(int)BinaryOperatorKind.UIntXor,
(int)BinaryOperatorKind.LongXor,
(int)BinaryOperatorKind.ULongXor,
(int)BinaryOperatorKind.NIntXor,
(int)BinaryOperatorKind.NUIntXor,
(int)BinaryOperatorKind.BoolXor,
(int)BinaryOperatorKind.LiftedIntXor,
(int)BinaryOperatorKind.LiftedUIntXor,
(int)BinaryOperatorKind.LiftedLongXor,
(int)BinaryOperatorKind.LiftedULongXor,
(int)BinaryOperatorKind.LiftedNIntXor,
(int)BinaryOperatorKind.LiftedNUIntXor,
(int)BinaryOperatorKind.LiftedBoolXor,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntOr,
(int)BinaryOperatorKind.UIntOr,
(int)BinaryOperatorKind.LongOr,
(int)BinaryOperatorKind.ULongOr,
(int)BinaryOperatorKind.NIntOr,
(int)BinaryOperatorKind.NUIntOr,
(int)BinaryOperatorKind.BoolOr,
(int)BinaryOperatorKind.LiftedIntOr,
(int)BinaryOperatorKind.LiftedUIntOr,
(int)BinaryOperatorKind.LiftedLongOr,
(int)BinaryOperatorKind.LiftedULongOr,
(int)BinaryOperatorKind.LiftedNIntOr,
(int)BinaryOperatorKind.LiftedNUIntOr,
(int)BinaryOperatorKind.LiftedBoolOr,
}),
GetSignaturesFromBinaryOperatorKinds(new []
{
(int)BinaryOperatorKind.IntUnsignedRightShift,
(int)BinaryOperatorKind.UIntUnsignedRightShift,
(int)BinaryOperatorKind.LongUnsignedRightShift,
(int)BinaryOperatorKind.ULongUnsignedRightShift,
(int)BinaryOperatorKind.NIntUnsignedRightShift,
(int)BinaryOperatorKind.NUIntUnsignedRightShift,
(int)BinaryOperatorKind.LiftedIntUnsignedRightShift,
(int)BinaryOperatorKind.LiftedUIntUnsignedRightShift,
(int)BinaryOperatorKind.LiftedLongUnsignedRightShift,
(int)BinaryOperatorKind.LiftedULongUnsignedRightShift,
(int)BinaryOperatorKind.LiftedNIntUnsignedRightShift,
(int)BinaryOperatorKind.LiftedNUIntUnsignedRightShift,
}),
};
var allOperators = new[] { nonLogicalOperators, logicalOperators };
Interlocked.CompareExchange(ref _builtInOperators, allOperators, null);
}
foreach (var op in _builtInOperators[kind.IsLogical() ? 1 : 0][kind.OperatorIndex()])
{
if (skipNativeIntegerOperators)
{
switch (op.Kind.OperandTypes())
{
case BinaryOperatorKind.NInt:
case BinaryOperatorKind.NUInt:
continue;
}
}
operators.Add(op);
}
}
internal void GetUtf8ConcatenationBuiltInOperator(TypeSymbol readonlySpanOfByte, ArrayBuilder<BinaryOperatorSignature> operators)
{
Debug.Assert(_compilation.IsReadOnlySpanType(readonlySpanOfByte));
Debug.Assert(((NamedTypeSymbol)readonlySpanOfByte).TypeArgumentsWithAnnotationsNoUseSiteDiagnostics.Single().Type.SpecialType is SpecialType.System_Byte);
var utfConcatenation = _builtInUtf8Concatenation.Initialize(
static readonlySpanOfByte => new BinaryOperatorSignature(BinaryOperatorKind.Utf8Addition, readonlySpanOfByte, readonlySpanOfByte, readonlySpanOfByte),
readonlySpanOfByte);
operators.Add(utfConcatenation);
}
internal BinaryOperatorSignature GetSignature(BinaryOperatorKind kind)
{
var left = LeftType(kind);
switch (kind.Operator())
{
case BinaryOperatorKind.Multiplication:
case BinaryOperatorKind.Division:
case BinaryOperatorKind.Subtraction:
case BinaryOperatorKind.Remainder:
case BinaryOperatorKind.And:
case BinaryOperatorKind.Or:
case BinaryOperatorKind.Xor:
return new BinaryOperatorSignature(kind, left, left, left);
case BinaryOperatorKind.Addition:
return new BinaryOperatorSignature(kind, left, RightType(kind), ReturnType(kind));
case BinaryOperatorKind.LeftShift:
case BinaryOperatorKind.RightShift:
case BinaryOperatorKind.UnsignedRightShift:
TypeSymbol rightType = _compilation.GetSpecialType(SpecialType.System_Int32);
if (kind.IsLifted())
{
rightType = _compilation.GetOrCreateNullableType(rightType);
}
return new BinaryOperatorSignature(kind, left, rightType, left);
case BinaryOperatorKind.Equal:
case BinaryOperatorKind.NotEqual:
case BinaryOperatorKind.GreaterThan:
case BinaryOperatorKind.LessThan:
case BinaryOperatorKind.GreaterThanOrEqual:
case BinaryOperatorKind.LessThanOrEqual:
return new BinaryOperatorSignature(kind, left, left, _compilation.GetSpecialType(SpecialType.System_Boolean));
}
return new BinaryOperatorSignature(kind, left, RightType(kind), ReturnType(kind));
}
private TypeSymbol LeftType(BinaryOperatorKind kind)
{
if (kind.IsLifted())
{
return LiftedType(kind);
}
else
{
switch (kind.OperandTypes())
{
case BinaryOperatorKind.Int: return _compilation.GetSpecialType(SpecialType.System_Int32);
case BinaryOperatorKind.UInt: return _compilation.GetSpecialType(SpecialType.System_UInt32);
case BinaryOperatorKind.Long: return _compilation.GetSpecialType(SpecialType.System_Int64);
case BinaryOperatorKind.ULong: return _compilation.GetSpecialType(SpecialType.System_UInt64);
case BinaryOperatorKind.NInt: return _compilation.CreateNativeIntegerTypeSymbol(signed: true);
case BinaryOperatorKind.NUInt: return _compilation.CreateNativeIntegerTypeSymbol(signed: false);
case BinaryOperatorKind.Float: return _compilation.GetSpecialType(SpecialType.System_Single);
case BinaryOperatorKind.Double: return _compilation.GetSpecialType(SpecialType.System_Double);
case BinaryOperatorKind.Decimal: return _compilation.GetSpecialType(SpecialType.System_Decimal);
case BinaryOperatorKind.Bool: return _compilation.GetSpecialType(SpecialType.System_Boolean);
case BinaryOperatorKind.ObjectAndString:
case BinaryOperatorKind.Object:
return _compilation.GetSpecialType(SpecialType.System_Object);
case BinaryOperatorKind.String:
case BinaryOperatorKind.StringAndObject:
return _compilation.GetSpecialType(SpecialType.System_String);
}
}
Debug.Assert(false, "Bad operator kind in left type");
return null;
}
private TypeSymbol RightType(BinaryOperatorKind kind)
{
if (kind.IsLifted())
{
return LiftedType(kind);
}
else
{
switch (kind.OperandTypes())
{
case BinaryOperatorKind.Int: return _compilation.GetSpecialType(SpecialType.System_Int32);
case BinaryOperatorKind.UInt: return _compilation.GetSpecialType(SpecialType.System_UInt32);
case BinaryOperatorKind.Long: return _compilation.GetSpecialType(SpecialType.System_Int64);
case BinaryOperatorKind.ULong: return _compilation.GetSpecialType(SpecialType.System_UInt64);
case BinaryOperatorKind.NInt: return _compilation.CreateNativeIntegerTypeSymbol(signed: true);
case BinaryOperatorKind.NUInt: return _compilation.CreateNativeIntegerTypeSymbol(signed: false);
case BinaryOperatorKind.Float: return _compilation.GetSpecialType(SpecialType.System_Single);
case BinaryOperatorKind.Double: return _compilation.GetSpecialType(SpecialType.System_Double);
case BinaryOperatorKind.Decimal: return _compilation.GetSpecialType(SpecialType.System_Decimal);
case BinaryOperatorKind.Bool: return _compilation.GetSpecialType(SpecialType.System_Boolean);
case BinaryOperatorKind.ObjectAndString:
case BinaryOperatorKind.String:
return _compilation.GetSpecialType(SpecialType.System_String);
case BinaryOperatorKind.StringAndObject:
case BinaryOperatorKind.Object:
return _compilation.GetSpecialType(SpecialType.System_Object);
}
}
Debug.Assert(false, "Bad operator kind in right type");
return null;
}
private TypeSymbol ReturnType(BinaryOperatorKind kind)
{
if (kind.IsLifted())
{
return LiftedType(kind);
}
else
{
switch (kind.OperandTypes())
{
case BinaryOperatorKind.Int: return _compilation.GetSpecialType(SpecialType.System_Int32);
case BinaryOperatorKind.UInt: return _compilation.GetSpecialType(SpecialType.System_UInt32);
case BinaryOperatorKind.Long: return _compilation.GetSpecialType(SpecialType.System_Int64);
case BinaryOperatorKind.ULong: return _compilation.GetSpecialType(SpecialType.System_UInt64);
case BinaryOperatorKind.NInt: return _compilation.CreateNativeIntegerTypeSymbol(signed: true);
case BinaryOperatorKind.NUInt: return _compilation.CreateNativeIntegerTypeSymbol(signed: false);
case BinaryOperatorKind.Float: return _compilation.GetSpecialType(SpecialType.System_Single);
case BinaryOperatorKind.Double: return _compilation.GetSpecialType(SpecialType.System_Double);
case BinaryOperatorKind.Decimal: return _compilation.GetSpecialType(SpecialType.System_Decimal);
case BinaryOperatorKind.Bool: return _compilation.GetSpecialType(SpecialType.System_Boolean);
case BinaryOperatorKind.Object: return _compilation.GetSpecialType(SpecialType.System_Object);
case BinaryOperatorKind.ObjectAndString:
case BinaryOperatorKind.StringAndObject:
case BinaryOperatorKind.String:
return _compilation.GetSpecialType(SpecialType.System_String);
}
}
Debug.Assert(false, "Bad operator kind in return type");
return null;
}
private TypeSymbol LiftedType(BinaryOperatorKind kind)
{
Debug.Assert(kind.IsLifted());
var typeArgument = kind.OperandTypes() switch
{
BinaryOperatorKind.Int => _compilation.GetSpecialType(SpecialType.System_Int32),
BinaryOperatorKind.UInt => _compilation.GetSpecialType(SpecialType.System_UInt32),
BinaryOperatorKind.Long => _compilation.GetSpecialType(SpecialType.System_Int64),
BinaryOperatorKind.ULong => _compilation.GetSpecialType(SpecialType.System_UInt64),
BinaryOperatorKind.NInt => _compilation.CreateNativeIntegerTypeSymbol(signed: true),
BinaryOperatorKind.NUInt => _compilation.CreateNativeIntegerTypeSymbol(signed: false),
BinaryOperatorKind.Float => _compilation.GetSpecialType(SpecialType.System_Single),
BinaryOperatorKind.Double => _compilation.GetSpecialType(SpecialType.System_Double),
BinaryOperatorKind.Decimal => _compilation.GetSpecialType(SpecialType.System_Decimal),
BinaryOperatorKind.Bool => _compilation.GetSpecialType(SpecialType.System_Boolean),
var v => throw ExceptionUtilities.UnexpectedValue(v),
};
return _compilation.GetOrCreateNullableType(typeArgument);
}
internal static bool IsValidObjectEquality(Conversions Conversions, TypeSymbol leftType, bool leftIsNull, bool leftIsDefault, TypeSymbol rightType, bool rightIsNull, bool rightIsDefault, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
// SPEC: The predefined reference type equality operators require one of the following:
// SPEC: (1) Both operands are a value of a type known to be a reference-type or the literal null.
// SPEC: Furthermore, an explicit reference conversion exists from the type of either
// SPEC: operand to the type of the other operand. Or:
// SPEC: (2) One operand is a value of type T where T is a type-parameter and the other operand is
// SPEC: the literal null. Furthermore T does not have the value type constraint.
// SPEC: (3) One operand is the literal default and the other operand is a reference-type.
// SPEC ERROR: Notice that the spec calls out that an explicit reference conversion must exist;
// SPEC ERROR: in fact it should say that an explicit reference conversion, implicit reference
// SPEC ERROR: conversion or identity conversion must exist. The conversion from object to object
// SPEC ERROR: is not classified as a reference conversion at all; it is an identity conversion.
// Dev10 does not follow the spec exactly for type parameters. Specifically, in Dev10,
// if a type parameter argument is known to be a value type, or if a type parameter
// argument is not known to be either a value type or reference type and the other
// argument is not null, reference type equality cannot be applied. Otherwise, the
// effective base class of the type parameter is used to determine the conversion
// to the other argument type. (See ExpressionBinder::GetRefEqualSigs.)
if (((object)leftType != null) && leftType.IsTypeParameter())
{
if (leftType.IsValueType || (!leftType.IsReferenceType && !rightIsNull))
{
return false;
}
leftType = ((TypeParameterSymbol)leftType).EffectiveBaseClass(ref useSiteInfo);
Debug.Assert((object)leftType != null);
}
if (((object)rightType != null) && rightType.IsTypeParameter())
{
if (rightType.IsValueType || (!rightType.IsReferenceType && !leftIsNull))
{
return false;
}
rightType = ((TypeParameterSymbol)rightType).EffectiveBaseClass(ref useSiteInfo);
Debug.Assert((object)rightType != null);
}
var leftIsReferenceType = ((object)leftType != null) && leftType.IsReferenceType;
if (!leftIsReferenceType && !leftIsNull && !leftIsDefault)
{
return false;
}
var rightIsReferenceType = ((object)rightType != null) && rightType.IsReferenceType;
if (!rightIsReferenceType && !rightIsNull && !rightIsDefault)
{
return false;
}
if (leftIsDefault && rightIsDefault)
{
return false;
}
if (leftIsDefault && rightIsNull)
{
return false;
}
if (leftIsNull && rightIsDefault)
{
return false;
}
// If at least one side is null or default then clearly a conversion exists.
if (leftIsNull || rightIsNull || leftIsDefault || rightIsDefault)
{
return true;
}
var leftConversion = Conversions.ClassifyConversionFromType(leftType, rightType, isChecked: false, ref useSiteInfo);
if (leftConversion.IsIdentity || leftConversion.IsReference)
{
return true;
}
var rightConversion = Conversions.ClassifyConversionFromType(rightType, leftType, isChecked: false, ref useSiteInfo);
if (rightConversion.IsIdentity || rightConversion.IsReference)
{
return true;
}
return false;
}
}
}
|