private MethodKind ComputeMethodKind()
{
if (this.HasSpecialName)
{
if (_name.StartsWith(".", StringComparison.Ordinal))
{
// 10.5.1 Instance constructor
// An instance constructor shall be an instance (not static or virtual) method,
// it shall be named .ctor, and marked instance, rtspecialname, and specialname (§15.4.2.6).
// An instance constructor can have parameters, but shall not return a value.
// An instance constructor cannot take generic type parameters.
// 10.5.3 Type initializer
// This method shall be static, take no parameters, return no value,
// be marked with rtspecialname and specialname (§15.4.2.6), and be named .cctor.
if ((Flags & (MethodAttributes.RTSpecialName | MethodAttributes.Virtual)) == MethodAttributes.RTSpecialName &&
_name.Equals(this.IsStatic ? WellKnownMemberNames.StaticConstructorName : WellKnownMemberNames.InstanceConstructorName) &&
this.ReturnsVoid && this.Arity == 0)
{
if (this.IsStatic)
{
if (Parameters.Length == 0)
{
return MethodKind.StaticConstructor;
}
}
else
{
return MethodKind.Constructor;
}
}
return MethodKind.Ordinary;
}
if (!this.HasRuntimeSpecialName && this.IsStatic && this.DeclaredAccessibility == Accessibility.Public)
{
switch (_name)
{
case WellKnownMemberNames.AdditionOperatorName:
case WellKnownMemberNames.BitwiseAndOperatorName:
case WellKnownMemberNames.BitwiseOrOperatorName:
case WellKnownMemberNames.DivisionOperatorName:
case WellKnownMemberNames.EqualityOperatorName:
case WellKnownMemberNames.ExclusiveOrOperatorName:
case WellKnownMemberNames.GreaterThanOperatorName:
case WellKnownMemberNames.GreaterThanOrEqualOperatorName:
case WellKnownMemberNames.InequalityOperatorName:
case WellKnownMemberNames.LeftShiftOperatorName:
case WellKnownMemberNames.LessThanOperatorName:
case WellKnownMemberNames.LessThanOrEqualOperatorName:
case WellKnownMemberNames.ModulusOperatorName:
case WellKnownMemberNames.MultiplyOperatorName:
case WellKnownMemberNames.RightShiftOperatorName:
case WellKnownMemberNames.SubtractionOperatorName:
return IsValidUserDefinedOperatorSignature(2) ? MethodKind.UserDefinedOperator : MethodKind.Ordinary;
case WellKnownMemberNames.DecrementOperatorName:
case WellKnownMemberNames.FalseOperatorName:
case WellKnownMemberNames.IncrementOperatorName:
case WellKnownMemberNames.LogicalNotOperatorName:
case WellKnownMemberNames.OnesComplementOperatorName:
case WellKnownMemberNames.TrueOperatorName:
case WellKnownMemberNames.UnaryNegationOperatorName:
case WellKnownMemberNames.UnaryPlusOperatorName:
return IsValidUserDefinedOperatorSignature(1) ? MethodKind.UserDefinedOperator : MethodKind.Ordinary;
case WellKnownMemberNames.ImplicitConversionName:
case WellKnownMemberNames.ExplicitConversionName:
return IsValidUserDefinedOperatorSignature(1) ? MethodKind.Conversion : MethodKind.Ordinary;
// UNDONE: Non-C#-supported overloaded operator case WellKnownMemberNames.ConcatenateOperatorName:
// UNDONE: Non-C#-supported overloaded operator case WellKnownMemberNames.ExponentOperatorName:
// UNDONE: Non-C#-supported overloaded operator case WellKnownMemberNames.IntegerDivisionOperatorName:
// UNDONE: Non-C#-supported overloaded operator case WellKnownMemberNames.LikeOperatorName:
}
return MethodKind.Ordinary;
}
}
if (!this.IsStatic)
{
switch (_name)
{
case WellKnownMemberNames.DestructorName:
if ((this.ContainingType.TypeKind == TypeKind.Class) || // && this.IsRuntimeFinalizer(skipFirstMethodKindCheck: true)) ||
this.IsExplicitFinalizerOverride)
{
return MethodKind.Destructor;
}
break;
case WellKnownMemberNames.DelegateInvokeName:
if (_containingType.TypeKind == TypeKind.Delegate)
{
return MethodKind.DelegateInvoke;
}
break;
default:
//// Note: this is expensive, so check it last
//// Note: method being processed may have an explicit method .override but still be
//// publicly accessible, the decision here is being made based on the method's name
//if (!SyntaxFacts.IsValidIdentifier(this.Name) && !this.ExplicitInterfaceImplementations.IsEmpty)
//{
// return MethodKind.ExplicitInterfaceImplementation;
//}
break;
}
}
return MethodKind.Ordinary;
}