212 lines
10 KiB
C#
212 lines
10 KiB
C#
using System.Threading;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Microsoft.CodeAnalysis.Text;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
|
|
internal sealed class SourceConstructorSymbol : SourceConstructorSymbolBase
|
|
{
|
|
private readonly bool _hasThisInitializer;
|
|
|
|
protected override bool AllowRefOrOut => true;
|
|
|
|
public static SourceConstructorSymbol CreateConstructorSymbol(SourceMemberContainerTypeSymbol containingType, ConstructorDeclarationSyntax syntax, bool isNullableAnalysisEnabled, BindingDiagnosticBag diagnostics)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
|
|
MethodKind methodKind = (MethodKind)((!syntax.Modifiers.Any(SyntaxKind.StaticKeyword)) ? 1 : 14);
|
|
SyntaxToken identifier = syntax.Identifier;
|
|
return new SourceConstructorSymbol(containingType, ((SyntaxToken)(ref identifier)).GetLocation(), syntax, methodKind, isNullableAnalysisEnabled, diagnostics);
|
|
}
|
|
|
|
private SourceConstructorSymbol(SourceMemberContainerTypeSymbol containingType, Location location, ConstructorDeclarationSyntax syntax, MethodKind methodKind, bool isNullableAnalysisEnabled, BindingDiagnosticBag diagnostics)
|
|
: base(containingType, location, syntax, SyntaxFacts.HasYieldOperations((SyntaxNode?)(object)syntax), MakeModifiersAndFlags(containingType, syntax, methodKind, isNullableAnalysisEnabled, location, diagnostics, out var modifierErrors, out var report_ERR_StaticConstructorWithAccessModifiers))
|
|
{
|
|
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00e5: Invalid comparison between Unknown and I4
|
|
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a4: Invalid comparison between Unknown and I4
|
|
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
|
|
ConstructorInitializerSyntax? initializer = syntax.Initializer;
|
|
_hasThisInitializer = initializer != null && initializer.Kind() == SyntaxKind.ThisConstructorInitializer;
|
|
this.CheckUnsafeModifier(DeclarationModifiers, diagnostics);
|
|
if (report_ERR_StaticConstructorWithAccessModifiers)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_StaticConstructorWithAccessModifiers, location, this);
|
|
}
|
|
SyntaxToken identifier = syntax.Identifier;
|
|
if (((SyntaxToken)(ref identifier)).ValueText != containingType.Name)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_MemberNeedsType, location);
|
|
}
|
|
bool flag = syntax.HasAnyBody();
|
|
if (IsExtern)
|
|
{
|
|
if ((int)methodKind == 1 && syntax.Initializer != null)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_ExternHasConstructorInitializer, location, this);
|
|
}
|
|
if (flag)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_ExternHasBody, location, this);
|
|
}
|
|
}
|
|
if ((int)methodKind == 14)
|
|
{
|
|
CheckFeatureAvailabilityAndRuntimeSupport((SyntaxNode)(object)syntax, location, flag, diagnostics);
|
|
}
|
|
ModifierUtils.CheckAccessibility(DeclarationModifiers, this, isExplicitInterfaceImplementation: false, diagnostics, location);
|
|
if (!modifierErrors)
|
|
{
|
|
CheckModifiers(methodKind, flag, location, diagnostics);
|
|
}
|
|
Symbol.CheckForBlockAndExpressionBody(syntax.Body, syntax.ExpressionBody, syntax, diagnostics);
|
|
}
|
|
|
|
private static (DeclarationModifiers, Flags) MakeModifiersAndFlags(NamedTypeSymbol containingType, ConstructorDeclarationSyntax syntax, MethodKind methodKind, bool isNullableAnalysisEnabled, Location location, BindingDiagnosticBag diagnostics, out bool modifierErrors, out bool report_ERR_StaticConstructorWithAccessModifiers)
|
|
{
|
|
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
|
|
DeclarationModifiers declarationModifiers = MakeModifiers(containingType, syntax, methodKind, syntax.HasAnyBody(), location, diagnostics, out modifierErrors, out report_ERR_StaticConstructorWithAccessModifiers);
|
|
bool isExpressionBodied = syntax.IsExpressionBodied();
|
|
bool isVarArg = syntax.IsVarArg();
|
|
Flags item = SourceMemberMethodSymbol.MakeFlags(methodKind, (RefKind)0, declarationModifiers, returnsVoid: true, returnsVoidIsSet: true, isExpressionBodied, isExtensionMethod: false, isNullableAnalysisEnabled, isVarArg, isExplicitInterfaceImplementation: false);
|
|
return (declarationModifiers, item);
|
|
}
|
|
|
|
internal ConstructorDeclarationSyntax GetSyntax()
|
|
{
|
|
return (ConstructorDeclarationSyntax)(object)syntaxReferenceOpt.GetSyntax(default(CancellationToken));
|
|
}
|
|
|
|
internal override ExecutableCodeBinder TryGetBodyBinder(BinderFactory binderFactoryOpt = null, bool ignoreAccessibility = false)
|
|
{
|
|
return TryGetBodyBinderFromSyntax(binderFactoryOpt, ignoreAccessibility);
|
|
}
|
|
|
|
protected override ParameterListSyntax GetParameterList()
|
|
{
|
|
return GetSyntax().ParameterList;
|
|
}
|
|
|
|
protected override CSharpSyntaxNode GetInitializer()
|
|
{
|
|
return GetSyntax().Initializer;
|
|
}
|
|
|
|
private static DeclarationModifiers MakeModifiers(NamedTypeSymbol containingType, ConstructorDeclarationSyntax syntax, MethodKind methodKind, bool hasBody, Location location, BindingDiagnosticBag diagnostics, out bool modifierErrors, out bool report_ERR_StaticConstructorWithAccessModifiers)
|
|
{
|
|
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0003: Invalid comparison between Unknown and I4
|
|
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0036: Invalid comparison between Unknown and I4
|
|
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
|
|
DeclarationModifiers defaultAccess = (((int)methodKind != 14) ? DeclarationModifiers.Private : DeclarationModifiers.None);
|
|
bool isInterface = containingType.IsInterface;
|
|
DeclarationModifiers declarationModifiers = ModifierUtils.MakeAndCheckNonTypeMemberModifiers(isOrdinaryMethod: false, isInterface, syntax.Modifiers, defaultAccess, DeclarationModifiers.AccessibilityMask | DeclarationModifiers.Static | DeclarationModifiers.Extern | DeclarationModifiers.Unsafe, location, diagnostics, out modifierErrors);
|
|
report_ERR_StaticConstructorWithAccessModifiers = false;
|
|
if ((int)methodKind == 14)
|
|
{
|
|
if ((declarationModifiers & DeclarationModifiers.AccessibilityMask) != DeclarationModifiers.None)
|
|
{
|
|
string name = containingType.Name;
|
|
SyntaxToken identifier = syntax.Identifier;
|
|
if (name == ((SyntaxToken)(ref identifier)).ValueText)
|
|
{
|
|
declarationModifiers = (DeclarationModifiers)((uint)declarationModifiers & 0xFFFFFC0Fu);
|
|
report_ERR_StaticConstructorWithAccessModifiers = true;
|
|
modifierErrors = true;
|
|
}
|
|
}
|
|
declarationModifiers |= DeclarationModifiers.Private;
|
|
if (isInterface)
|
|
{
|
|
ModifierUtils.ReportDefaultInterfaceImplementationModifiers(hasBody, declarationModifiers, DeclarationModifiers.Extern, location, diagnostics);
|
|
}
|
|
}
|
|
return declarationModifiers;
|
|
}
|
|
|
|
private void CheckModifiers(MethodKind methodKind, bool hasBody, Location location, BindingDiagnosticBag diagnostics)
|
|
{
|
|
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0074: Invalid comparison between Unknown and I4
|
|
if (!hasBody && !IsExtern)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_ConcreteMissingBody, location, this);
|
|
}
|
|
else if (ContainingType.IsSealed && DeclaredAccessibility.HasProtected() && !IsOverride)
|
|
{
|
|
diagnostics.Add(AccessCheck.GetProtectedMemberInSealedTypeError(ContainingType), location, this);
|
|
}
|
|
else if (ContainingType.IsStatic && (int)methodKind == 1)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_ConstructorInStaticClass, location);
|
|
}
|
|
}
|
|
|
|
internal override OneOrMany<SyntaxList<AttributeListSyntax>> GetAttributeDeclarations()
|
|
{
|
|
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
return OneOrMany.Create<SyntaxList<AttributeListSyntax>>(((ConstructorDeclarationSyntax)SyntaxNode).AttributeLists);
|
|
}
|
|
|
|
internal override bool IsNullableAnalysisEnabled()
|
|
{
|
|
if (!_hasThisInitializer)
|
|
{
|
|
return ((SourceMemberContainerTypeSymbol)ContainingType).IsNullableEnabledForConstructorsAndInitializers(IsStatic);
|
|
}
|
|
return flags.IsNullableAnalysisEnabled;
|
|
}
|
|
|
|
protected override bool IsWithinExpressionOrBlockBody(int position, out int offset)
|
|
{
|
|
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
|
|
ConstructorDeclarationSyntax syntax = GetSyntax();
|
|
BlockSyntax? body = syntax.Body;
|
|
TextSpan span;
|
|
if (body != null)
|
|
{
|
|
span = ((SyntaxNode)body).Span;
|
|
if (((TextSpan)(ref span)).Contains(position))
|
|
{
|
|
span = ((SyntaxNode)syntax.Body).Span;
|
|
offset = position - ((TextSpan)(ref span)).Start;
|
|
return true;
|
|
}
|
|
}
|
|
ArrowExpressionClauseSyntax? expressionBody = syntax.ExpressionBody;
|
|
if (expressionBody != null)
|
|
{
|
|
span = ((SyntaxNode)expressionBody).Span;
|
|
if (((TextSpan)(ref span)).Contains(position))
|
|
{
|
|
span = ((SyntaxNode)syntax.ExpressionBody).Span;
|
|
offset = position - ((TextSpan)(ref span)).Start;
|
|
return true;
|
|
}
|
|
}
|
|
offset = -1;
|
|
return false;
|
|
}
|
|
}
|