Beispiel #1
0
        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());
            }
        }
Beispiel #2
0
        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))));
        }
Beispiel #3
0
        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))));
        }
Beispiel #4
0
        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);
        }