private SourceMemberMethodSymbol(
            NamedTypeSymbol containingType,
            TypeSymbol explicitInterfaceType,
            string name,
            Location location,
            MethodDeclarationSyntax syntax,
            MethodKind methodKind,
            DiagnosticBag diagnostics) :
            base(containingType,
                 syntax.GetReference(),
                 // Prefer a block body if both exist
                 syntax.Body?.GetReference() ?? syntax.ExpressionBody?.GetReference(),
                 location)
        {
            _name = name;
            _explicitInterfaceType = explicitInterfaceType;

            SyntaxTokenList modifiers = syntax.Modifiers;

            // The following two values are used to compute and store the initial value of the flags
            // However, these two components are placeholders; the correct value will be
            // computed lazily later and then the flags will be fixed up.
            const bool returnsVoid = false;

            var firstParam = syntax.ParameterList.Parameters.FirstOrDefault();
            bool isExtensionMethod = firstParam != null &&
                !firstParam.IsArgList &&
                firstParam.Modifiers.Any(SyntaxKind.ThisKeyword);

            bool modifierErrors;
            var declarationModifiers = this.MakeModifiers(modifiers, methodKind, location, diagnostics, out modifierErrors);

            var isMetadataVirtualIgnoringModifiers = (object)explicitInterfaceType != null; //explicit impls must be marked metadata virtual

            this.MakeFlags(methodKind, declarationModifiers, returnsVoid, isExtensionMethod, isMetadataVirtualIgnoringModifiers);

            _typeParameters = (syntax.Arity == 0) ?
                ImmutableArray<TypeParameterSymbol>.Empty :
                MakeTypeParameters(syntax, diagnostics);

            bool hasBlockBody = syntax.Body != null;
            _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null;

            if (hasBlockBody || _isExpressionBodied)
            {
                CheckModifiersForBody(location, diagnostics);
            }

            _refKind = syntax.RefKeyword.Kind().GetRefKind();

            var info = ModifierUtils.CheckAccessibility(this.DeclarationModifiers);
            if (info != null)
            {
                diagnostics.Add(info, location);
            }
        }
        private SourceMemberMethodSymbol(
            NamedTypeSymbol containingType,
            TypeSymbol explicitInterfaceType,
            string name,
            Location location,
            Binder bodyBinder,
            MethodDeclarationSyntax syntax,
            MethodKind methodKind,
            DiagnosticBag diagnostics) :
            base(containingType,
                 syntax.GetReference(),
                 // Prefer a block body if both exist
                 syntax.Body?.GetReference() ?? syntax.ExpressionBody?.GetReference(),
                 location)
        {
            _name = name;
            _explicitInterfaceType = explicitInterfaceType;

            SyntaxTokenList modifiers = syntax.Modifiers;

            // The following two values are used to compute and store the initial value of the flags
            // However, these two components are placeholders; the correct value will be
            // computed lazily later and then the flags will be fixed up.
            const bool returnsVoid = false;

            var firstParam = syntax.ParameterList.Parameters.FirstOrDefault();
            bool isExtensionMethod = firstParam != null &&
                !firstParam.IsArgList &&
                firstParam.Modifiers.Any(SyntaxKind.ThisKeyword);

            bool modifierErrors;
            var declarationModifiers = this.MakeModifiers(modifiers, methodKind, location, diagnostics, out modifierErrors);

            var isMetadataVirtualIgnoringModifiers = (object)explicitInterfaceType != null; //explicit impls must be marked metadata virtual

            this.MakeFlags(methodKind, declarationModifiers, returnsVoid, isExtensionMethod, isMetadataVirtualIgnoringModifiers);

            // NOTE: by creating a WithMethodTypeParametersBinder, we are effectively duplicating the
            // functionality of the BinderFactory.  Unfortunately, we cannot use the BinderFactory
            // because it depends on having access to the member list of our containing type and
            // that list cannot be complete because we're not finished constructing this member.
            // TODO: at least keep this in sync with BinderFactory.VisitMethodDeclaration.
            bodyBinder = bodyBinder.WithUnsafeRegionIfNecessary(modifiers);

            Binder withTypeParamsBinder;
            if (syntax.Arity == 0)
            {
                withTypeParamsBinder = bodyBinder;
                _typeParameters = ImmutableArray<TypeParameterSymbol>.Empty;
            }
            else
            {
                var parameterBinder = new WithMethodTypeParametersBinder(this, bodyBinder);
                withTypeParamsBinder = parameterBinder;
                _typeParameters = MakeTypeParameters(syntax, diagnostics);
            }

            bool hasBlockBody = syntax.Body != null;
            _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null;

            if (hasBlockBody || _isExpressionBodied)
            {
                CheckModifiersForBody(location, diagnostics);
            }

            var info = ModifierUtils.CheckAccessibility(this.DeclarationModifiers);
            if (info != null)
            {
                diagnostics.Add(info, location);
            }

            if (this.IsPartial)
            {
                // Partial methods must be completed early because they are matched up
                // by signature while producing the enclosing type's member list. However,
                // that means any type parameter constraints will be bound before the method
                // is added to the containing type. To enable binding of constraints before the
                // .ctor completes we hold on to the current binder while the .ctor is executing.
                // If we change the handling of partial methods, so that partial methods are
                // completed lazily, the 'constraintClauseBinder' field should be removed.
                _constraintClauseBinder = withTypeParamsBinder;

                state.NotePartComplete(CompletionPart.StartMethodChecks);
                MethodChecks(syntax, withTypeParamsBinder, diagnostics);
                state.NotePartComplete(CompletionPart.FinishMethodChecks);
                _constraintClauseBinder = null;
            }
        }