internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics) { var F = new SyntheticBoundNodeFactory(this, this.SyntaxNode, compilationState, diagnostics); try { var paramAccess = F.Parameter(Parameters[0]); BoundExpression expression; if (ContainingType.IsStructType()) { throw ExceptionUtilities.Unreachable; } else { if (_typedRecordEquals.ReturnType.SpecialType != SpecialType.System_Boolean) { // There is a signature mismatch, an error was reported elsewhere F.CloseMethod(F.ThrowNull()); return; } // For classes: // return this.Equals(param as ContainingType); expression = F.Call(F.This(), _typedRecordEquals, F.As(paramAccess, ContainingType)); } F.CloseMethod(F.Block(ImmutableArray.Create <BoundStatement>(F.Return(expression)))); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { diagnostics.Add(ex.Diagnostic); F.CloseMethod(F.ThrowNull()); } }
internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics) { var F = new SyntheticBoundNodeFactory(this, ContainingType.GetNonNullSyntaxNode(), compilationState, diagnostics); var paramAccess = F.Parameter(Parameters[0]); BoundExpression expression; if (ContainingType.IsStructType()) { // For structs: // // return param is ContainingType i ? this.Equals(in i) : false; expression = F.Conditional( F.Is(paramAccess, ContainingType), F.Call( F.This(), _typedRecordEquals, ImmutableArray.Create <RefKind>(RefKind.In), ImmutableArray.Create <BoundExpression>(F.Convert(ContainingType, paramAccess))), F.Literal(false), F.SpecialType(SpecialType.System_Boolean)); } else { // For classes: // return this.Equals(param as ContainingType); expression = F.Call(F.This(), _typedRecordEquals, F.As(paramAccess, ContainingType)); } F.CloseMethod(F.Block(ImmutableArray.Create <BoundStatement>(F.Return(expression)))); }
internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics) { var F = new SyntheticBoundNodeFactory(this, ContainingType.GetNonNullSyntaxNode(), compilationState, diagnostics); var paramAccess = F.Parameter(Parameters[0]); BoundExpression expression; if (ContainingType.IsStructType()) { throw ExceptionUtilities.Unreachable; } else { // For classes: // return this.Equals(param as ContainingType); expression = F.Call(F.This(), _typedRecordEquals, F.As(paramAccess, ContainingType)); } F.CloseMethod(F.Block(ImmutableArray.Create <BoundStatement>(F.Return(expression)))); }
private (DeclarationModifiers mods, bool hasExplicitAccessMod) MakeModifiers(MethodKind methodKind, bool isPartial, bool hasBody, Location location, DiagnosticBag diagnostics) { bool isInterface = this.ContainingType.IsInterface; bool isExplicitInterfaceImplementation = methodKind == MethodKind.ExplicitInterfaceImplementation; var defaultAccess = isInterface && isPartial && !isExplicitInterfaceImplementation ? DeclarationModifiers.Public : DeclarationModifiers.Private; // Check that the set of modifiers is allowed var allowedModifiers = DeclarationModifiers.Partial | DeclarationModifiers.Unsafe; var defaultInterfaceImplementationModifiers = DeclarationModifiers.None; if (!isExplicitInterfaceImplementation) { allowedModifiers |= DeclarationModifiers.New | DeclarationModifiers.Sealed | DeclarationModifiers.Abstract | DeclarationModifiers.Static | DeclarationModifiers.Virtual | DeclarationModifiers.AccessibilityMask; if (!isInterface) { allowedModifiers |= DeclarationModifiers.Override; } else { // This is needed to make sure we can detect 'public' modifier specified explicitly and // check it against language version below. defaultAccess = DeclarationModifiers.None; defaultInterfaceImplementationModifiers |= DeclarationModifiers.Sealed | DeclarationModifiers.Abstract | DeclarationModifiers.Static | DeclarationModifiers.Virtual | DeclarationModifiers.Extern | DeclarationModifiers.Async | DeclarationModifiers.Partial | DeclarationModifiers.AccessibilityMask; } } else if (isInterface) { Debug.Assert(isExplicitInterfaceImplementation); allowedModifiers |= DeclarationModifiers.Abstract; } allowedModifiers |= DeclarationModifiers.Extern | DeclarationModifiers.Async; if (ContainingType.IsStructType()) { allowedModifiers |= DeclarationModifiers.ReadOnly; } // In order to detect whether explicit accessibility mods were provided, we pass the default value // for 'defaultAccess' and manually add in the 'defaultAccess' flags after the call. bool hasExplicitAccessMod; DeclarationModifiers mods = MakeDeclarationModifiers(allowedModifiers, diagnostics); if ((mods & DeclarationModifiers.AccessibilityMask) == 0) { hasExplicitAccessMod = false; mods |= defaultAccess; } else { hasExplicitAccessMod = true; } this.CheckUnsafeModifier(mods, diagnostics); ModifierUtils.ReportDefaultInterfaceImplementationModifiers(hasBody, mods, defaultInterfaceImplementationModifiers, location, diagnostics); mods = AddImpliedModifiers(mods, isInterface, methodKind, hasBody); return(mods, hasExplicitAccessMod); }