Example #1
0
        protected override CSharpAttributeData CreateCompilerGeneratedAttribute()
        {
            Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
            var compilation = ModuleBeingBuilt.Compilation;

            return(compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
        }
Example #2
0
        public bool ReportMissingOrErroneousSymbols(BindingDiagnosticBag diagnostics)
        {
            bool hasErrors = false;

            ReportErrorOnSymbol(System_Object, diagnostics, ref hasErrors);
            ReportErrorOnSymbol(System_Void, diagnostics, ref hasErrors);
            ReportErrorOnSymbol(System_Boolean, diagnostics, ref hasErrors);
            ReportErrorOnSymbol(System_String, diagnostics, ref hasErrors);
            ReportErrorOnSymbol(System_Int32, diagnostics, ref hasErrors);

            ReportErrorOnSpecialMember(System_Object__Equals, SpecialMember.System_Object__Equals, diagnostics, ref hasErrors);
            ReportErrorOnSpecialMember(System_Object__ToString, SpecialMember.System_Object__ToString, diagnostics, ref hasErrors);
            ReportErrorOnSpecialMember(System_Object__GetHashCode, SpecialMember.System_Object__GetHashCode, diagnostics, ref hasErrors);
            ReportErrorOnWellKnownMember(System_String__Format_IFormatProvider, WellKnownMember.System_String__Format_IFormatProvider, diagnostics, ref hasErrors);

            // optional synthesized attributes:
            Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
            Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor));
            Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Diagnostics_DebuggerBrowsableAttribute__ctor));

            ReportErrorOnWellKnownMember(System_Collections_Generic_EqualityComparer_T__Equals,
                                         WellKnownMember.System_Collections_Generic_EqualityComparer_T__Equals,
                                         diagnostics, ref hasErrors);
            ReportErrorOnWellKnownMember(System_Collections_Generic_EqualityComparer_T__GetHashCode,
                                         WellKnownMember.System_Collections_Generic_EqualityComparer_T__GetHashCode,
                                         diagnostics, ref hasErrors);
            ReportErrorOnWellKnownMember(System_Collections_Generic_EqualityComparer_T__get_Default,
                                         WellKnownMember.System_Collections_Generic_EqualityComparer_T__get_Default,
                                         diagnostics, ref hasErrors);

            return(hasErrors);
        }
        // Useful for testing
        internal static bool Override(WellKnownMembers kind, string proto)
        {
            var name = proto.Replace("$", "").Split('(').First();
            var s    = Binder.LookupName(name);

            if (s == null)
            {
                return(false);
            }
            if (s is SymbolList)
            {
                var isStatic = proto.Contains('$');
                var args     = proto.Replace(")", "").Split('(').Last().Split(',');
                var argTypes = args.Select(x => Binder.LookupFullName(x) as TypeSymbol).ToArray();
                s = (s as SymbolList).Symbols.Find(x => (x as MethodBaseSymbol)?.MethodBase.GetParameters().Length == args.Length &&
                                                   (x as MethodBaseSymbol)?.MethodBase.IsStatic == isStatic &&
                                                   (x as MethodBaseSymbol)?.MethodBase.GetParameters().All(y => args[y.Position] == "*" || y.ParameterType == argTypes[y.Position].Type) == true);
                if (!(s is MethodBaseSymbol))
                {
                    return(false);
                }
            }
            if (!(s is MemberSymbol))
            {
                return(false);
            }
            WellKnownMemberSymbols[(int)kind] = s as MemberSymbol;
            return(true);
        }
Example #4
0
        /// <summary>
        /// Synthesizes a custom attribute.
        /// Returns null if the <paramref name="constructor"/> symbol is missing and the attribute is synthesized only if present.
        /// </summary>
        internal SynthesizedAttributeData SynthesizeAttribute(
            WellKnownMember constructor,
            ImmutableArray <TypedConstant> arguments = default(ImmutableArray <TypedConstant>),
            ImmutableArray <KeyValuePair <string, TypedConstant> > namedArguments = default(ImmutableArray <KeyValuePair <string, TypedConstant> >))
        {
            var ctorSymbol = (MethodSymbol)GetWellKnownTypeMember(constructor);

            if ((object)ctorSymbol == null)
            {
                // if this assert fails, UseSiteErrors for "member" have not been checked before emitting ...
                Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(constructor));
                return(null);
            }

            if (arguments.IsDefault)
            {
                arguments = ImmutableArray <TypedConstant> .Empty;
            }

            if (namedArguments.IsDefault)
            {
                namedArguments = ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty;
            }

            return(new SynthesizedAttributeData(ctorSymbol, arguments, namedArguments));
        }
        private static bool TryGetBuilderMember <TSymbol>(
            SyntheticBoundNodeFactory F,
            WellKnownMember?member,
            NamedTypeSymbol builderType,
            bool customBuilder,
            out TSymbol symbol
            ) where TSymbol : Symbol
        {
            if (!member.HasValue)
            {
                symbol = null;
                return(true);
            }

            WellKnownMember memberValue = member.Value;

            if (customBuilder)
            {
                var descriptor = WellKnownMembers.GetDescriptor(memberValue);
                var sym        = CSharpCompilation.GetRuntimeMember(
                    builderType.OriginalDefinition,
                    descriptor,
                    F.Compilation.WellKnownMemberSignatureComparer,
                    accessWithinOpt: null
                    );
                if ((object)sym != null)
                {
                    sym = sym.SymbolAsMember(builderType);
                }
                symbol = sym as TSymbol;
            }
            else
            {
                symbol = F.WellKnownMember(memberValue, isOptional: true) as TSymbol;
                if ((object)symbol != null)
                {
                    symbol = (TSymbol)symbol.SymbolAsMember(builderType);
                }
            }
            if ((object)symbol == null)
            {
                var descriptor = WellKnownMembers.GetDescriptor(memberValue);
                var diagnostic = new CSDiagnostic(
                    new CSDiagnosticInfo(
                        ErrorCode.ERR_MissingPredefinedMember,
                        (
                            customBuilder
                                ? (object)builderType
                                : descriptor.DeclaringTypeMetadataName
                        ),
                        descriptor.Name
                        ),
                    F.Syntax.Location
                    );
                F.Diagnostics.Add(diagnostic);
                return(false);
            }
            return(true);
        }
        internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes)
        {
            base.AddSynthesizedAttributes(moduleBuilder, ref attributes);
            Debug.Assert(IsImplicitlyDeclared);
            var compilation = this.DeclaringCompilation;

            AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
            Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
        }
Example #7
0
        /// <summary>
        /// Get the MethodSymbol for System.Threading.Interlocked.CompareExchange&lt;T&gt; for a given T.
        /// </summary>
        private static MethodSymbol GetConstructedCompareExchangeMethod(TypeSymbol typeArg, CSharpCompilation compilation, Location errorLocation, DiagnosticBag diagnostics)
        {
            MethodSymbol compareExchangeDefinition = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Threading_Interlocked__CompareExchange_T);

            if ((object)compareExchangeDefinition == null)
            {
                MemberDescriptor memberDescriptor = WellKnownMembers.GetDescriptor(WellKnownMember.System_Threading_Interlocked__CompareExchange_T);
                WellKnownType    containingType   = (WellKnownType)memberDescriptor.DeclaringTypeId;
                diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, errorLocation, containingType.GetMetadataName(), memberDescriptor.Name);
                return(null);
            }

            return(compareExchangeDefinition.Construct(ImmutableArray.Create <TypeSymbol>(typeArg)));
        }
        /// <summary>
        /// Synthesizes a custom attribute.
        /// Returns null if the <paramref name="constructor"/> symbol is missing,
        /// or any of the members in <paramref name="namedArguments" /> are missing.
        /// The attribute is synthesized only if present.
        /// </summary>
        /// <param name="constructor">
        /// Constructor of the attribute. If it doesn't exist, the attribute is not created.
        /// </param>
        /// <param name="arguments">Arguments to the attribute constructor.</param>
        /// <param name="namedArguments">
        /// Takes a list of pairs of well-known members and constants. The constants
        /// will be passed to the field/property referenced by the well-known member.
        /// If the well-known member does not exist in the compilation then no attribute
        /// will be synthesized.
        /// </param>
        /// <param name="isOptionalUse">
        /// Indicates if this particular attribute application should be considered optional.
        /// </param>
        internal SynthesizedAttributeData TrySynthesizeAttribute(
            WellKnownMember constructor,
            ImmutableArray <TypedConstant> arguments = default(ImmutableArray <TypedConstant>),
            ImmutableArray <KeyValuePair <WellKnownMember, TypedConstant> > namedArguments = default(ImmutableArray <KeyValuePair <WellKnownMember, TypedConstant> >),
            bool isOptionalUse = false)
        {
            DiagnosticInfo diagnosticInfo;
            var            ctorSymbol = (MethodSymbol)Binder.GetWellKnownTypeMember(this, constructor, out diagnosticInfo, isOptional: true);

            if ((object)ctorSymbol == null)
            {
                // if this assert fails, UseSiteErrors for "member" have not been checked before emitting ...
                Debug.Assert(isOptionalUse || WellKnownMembers.IsSynthesizedAttributeOptional(constructor));
                return(null);
            }

            if (arguments.IsDefault)
            {
                arguments = ImmutableArray <TypedConstant> .Empty;
            }

            ImmutableArray <KeyValuePair <string, TypedConstant> > namedStringArguments;

            if (namedArguments.IsDefault)
            {
                namedStringArguments = ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty;
            }
            else
            {
                var builder = new ArrayBuilder <KeyValuePair <string, TypedConstant> >(namedArguments.Length);
                foreach (var arg in namedArguments)
                {
                    var wellKnownMember = Binder.GetWellKnownTypeMember(this, arg.Key, out diagnosticInfo, isOptional: true);
                    if (wellKnownMember == null || wellKnownMember is ErrorTypeSymbol)
                    {
                        // if this assert fails, UseSiteErrors for "member" have not been checked before emitting ...
                        Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(constructor));
                        return(null);
                    }
                    else
                    {
                        builder.Add(new KeyValuePair <string, TypedConstant>(
                                        wellKnownMember.Name, arg.Value));
                    }
                }
                namedStringArguments = builder.ToImmutableAndFree();
            }

            return(new SynthesizedAttributeData(ctorSymbol, arguments, namedStringArguments));
        }
        /// <summary>
        /// Get the symbol for a well-known member. The use of this method to get a well-known member
        /// that does not exist will result in an exception of type MissingPredefinedMember being thrown
        /// containing an appropriate diagnostic for the caller to report.
        /// </summary>
        /// <param name="wm">The desired well-known member</param>
        /// <param name="isOptional">If true, the method may return null for a missing member without an exception</param>
        /// <returns>A symbol for the well-known member, or null if it is missing and isOptions == true</returns>
        public Symbol WellKnownMember(WellKnownMember wm, bool isOptional = false)
        {
            Symbol wellKnownMember = Binder.GetWellKnownTypeMember(Compilation, wm, Diagnostics, syntax: Syntax, isOptional: true);

            if (wellKnownMember == null && !isOptional)
            {
                RuntimeMembers.MemberDescriptor memberDescriptor = WellKnownMembers.GetDescriptor(wm);
                WellKnownType containingType = (WellKnownType)memberDescriptor.DeclaringTypeId;
                var           diagnostic     = new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, containingType.GetMetadataName(), memberDescriptor.Name), Syntax.Location);
                throw new MissingPredefinedMember(diagnostic);
            }

            return(wellKnownMember);
        }
Example #10
0
        /// <summary>
        /// Report diagnostics that should be reported when using a synthesized attribute.
        /// </summary>
        internal static void ReportUseSiteDiagnosticForSynthesizedAttribute(
            CSharpCompilation compilation,
            WellKnownMember attributeMember,
            DiagnosticBag diagnostics,
            Location location       = null,
            CSharpSyntaxNode syntax = null)
        {
            Debug.Assert((location != null) ^ (syntax != null));

            // Dev11 reports use-site diagnostics when an optional attribute is found but is bad for some other reason
            // (comes from an unified assembly). When the symbol is not found no error is reported. See test VersionUnification_UseSiteDiagnostics_OptionalAttributes.
            bool isOptional = WellKnownMembers.IsSynthesizedAttributeOptional(attributeMember);

            GetWellKnownTypeMember(compilation, attributeMember, diagnostics, location, syntax, isOptional);
        }
Example #11
0
 private static void ReportErrorOnWellKnownMember(Symbol symbol, WellKnownMember member, BindingDiagnosticBag diagnostics, ref bool hasError)
 {
     if ((object)symbol == null)
     {
         MemberDescriptor memberDescriptor = WellKnownMembers.GetDescriptor(member);
         diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, NoLocation.Singleton,
                         memberDescriptor.DeclaringTypeMetadataName, memberDescriptor.Name);
         hasError = true;
     }
     else
     {
         ReportErrorOnSymbol(symbol, diagnostics, ref hasError);
         ReportErrorOnSymbol(symbol.ContainingType, diagnostics, ref hasError);
     }
 }
Example #12
0
        /// <summary>
        /// Lookup member declaration in well known type used by this Compilation.
        /// </summary>
        /// <remarks>
        /// If a well-known member of a generic type instantiation is needed use this method to get the corresponding generic definition and
        /// <see cref="MethodSymbol.AsMember"/> to construct an instantiation.
        /// </remarks>
        internal Symbol GetWellKnownTypeMember(WellKnownMember member)
        {
            Debug.Assert(member >= 0 && member < WellKnownMember.Count);

            // Test hook: if a member is marked missing, then return null.
            if (IsMemberMissing(member))
            {
                return(null);
            }

            if (_lazyWellKnownTypeMembers == null || ReferenceEquals(_lazyWellKnownTypeMembers[(int)member], ErrorTypeSymbol.UnknownResultType))
            {
                if (_lazyWellKnownTypeMembers == null)
                {
                    var wellKnownTypeMembers = new Symbol[(int)WellKnownMember.Count];

                    for (int i = 0; i < wellKnownTypeMembers.Length; i++)
                    {
                        wellKnownTypeMembers[i] = ErrorTypeSymbol.UnknownResultType;
                    }

                    Interlocked.CompareExchange(ref _lazyWellKnownTypeMembers, wellKnownTypeMembers, null);
                }

                MemberDescriptor descriptor = WellKnownMembers.GetDescriptor(member);
                NamedTypeSymbol  type       = descriptor.DeclaringTypeId <= (int)SpecialType.Count
                                            ? this.GetSpecialType((SpecialType)descriptor.DeclaringTypeId)
                                            : this.GetWellKnownType((WellKnownType)descriptor.DeclaringTypeId);
                Symbol result = null;

                if (!type.IsErrorType())
                {
                    result = GetRuntimeMember(type, ref descriptor, _wellKnownMemberSignatureComparer, accessWithinOpt: this.Assembly);
                }

                Interlocked.CompareExchange(ref _lazyWellKnownTypeMembers[(int)member], result, ErrorTypeSymbol.UnknownResultType);
            }

            return(_lazyWellKnownTypeMembers[(int)member]);
        }
Example #13
0
        private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsBinder, DiagnosticBag diagnostics)
        {
            SyntaxToken arglistToken;

            // Constraint checking for parameter and return types must be delayed until
            // the method has been added to the containing type member list since
            // evaluating the constraints may depend on accessing this method from
            // the container (comparing this method to others to find overrides for
            // instance). Constraints are checked in AfterAddingTypeMembersChecks.
            var signatureBinder = withTypeParamsBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this);

            _lazyParameters = ParameterHelpers.MakeParameters(signatureBinder, this, syntax.ParameterList, true, out arglistToken, diagnostics, false);
            _lazyIsVararg   = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
            RefKind refKind;
            var     returnTypeSyntax = syntax.ReturnType.SkipRef(out refKind);

            _lazyReturnType = signatureBinder.BindType(returnTypeSyntax, diagnostics);

            if (_lazyReturnType.IsRestrictedType())
            {
                if (_lazyReturnType.SpecialType == SpecialType.System_TypedReference &&
                    (this.ContainingType.SpecialType == SpecialType.System_TypedReference || this.ContainingType.SpecialType == SpecialType.System_ArgIterator))
                {
                    // Two special cases: methods in the special types TypedReference and ArgIterator are allowed to return TypedReference
                }
                else
                {
                    // Method or delegate cannot return type '{0}'
                    diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, syntax.ReturnType.Location, _lazyReturnType);
                }
            }

            var returnsVoid = _lazyReturnType.SpecialType == SpecialType.System_Void;

            if (this.RefKind != RefKind.None && returnsVoid)
            {
                Debug.Assert(returnTypeSyntax.HasErrors);
            }

            // set ReturnsVoid flag
            this.SetReturnsVoid(returnsVoid);

            var location = this.Locations[0];

            this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);

            // Checks taken from MemberDefiner::defineMethod
            if (this.Name == WellKnownMemberNames.DestructorName && this.ParameterCount == 0 && this.Arity == 0 && this.ReturnsVoid)
            {
                diagnostics.Add(ErrorCode.WRN_FinalizeMethod, location);
            }

            // errors relevant for extension methods
            if (IsExtensionMethod)
            {
                var parameter0Type = this.Parameters[0].Type;
                if (!parameter0Type.IsValidExtensionParameterType())
                {
                    // Duplicate Dev10 behavior by selecting the parameter type.
                    var parameterSyntax = syntax.ParameterList.Parameters[0];
                    Debug.Assert(parameterSyntax.Type != null);
                    var loc = parameterSyntax.Type.Location;
                    diagnostics.Add(ErrorCode.ERR_BadTypeforThis, loc, parameter0Type);
                }
                else if ((object)ContainingType.ContainingType != null)
                {
                    diagnostics.Add(ErrorCode.ERR_ExtensionMethodsDecl, location, ContainingType.Name);
                }
                else if (!ContainingType.IsScriptClass && !(ContainingType.IsStatic && ContainingType.Arity == 0))
                {
                    // Duplicate Dev10 behavior by selecting the containing type identifier. However if there
                    // is no containing type (in the interactive case for instance), select the method identifier.
                    var typeDecl   = syntax.Parent as TypeDeclarationSyntax;
                    var identifier = (typeDecl != null) ? typeDecl.Identifier : syntax.Identifier;
                    var loc        = identifier.GetLocation();
                    diagnostics.Add(ErrorCode.ERR_BadExtensionAgg, loc);
                }
                else if (!IsStatic)
                {
                    diagnostics.Add(ErrorCode.ERR_BadExtensionMeth, location);
                }
                else
                {
                    // Verify ExtensionAttribute is available.
                    var attributeConstructor = withTypeParamsBinder.Compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor);
                    if ((object)attributeConstructor == null)
                    {
                        var memberDescriptor = WellKnownMembers.GetDescriptor(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor);
                        // do not use Binder.ReportUseSiteErrorForAttributeCtor in this case, because we'll need to report a special error id, not a generic use site error.
                        diagnostics.Add(
                            ErrorCode.ERR_ExtensionAttrNotFound,
                            syntax.ParameterList.Parameters[0].Modifiers.FirstOrDefault(SyntaxKind.ThisKeyword).GetLocation(),
                            memberDescriptor.DeclaringTypeMetadataName);
                    }
                }
            }

            if (this.MethodKind == MethodKind.UserDefinedOperator)
            {
                foreach (var p in this.Parameters)
                {
                    if (p.RefKind != RefKind.None)
                    {
                        diagnostics.Add(ErrorCode.ERR_IllegalRefParam, location);
                        break;
                    }
                }
            }
            else if (IsPartial)
            {
                // check that there are no out parameters in a partial
                foreach (var p in this.Parameters)
                {
                    if (p.RefKind == RefKind.Out)
                    {
                        diagnostics.Add(ErrorCode.ERR_PartialMethodCannotHaveOutParameters, location);
                        break;
                    }
                }

                if (MethodKind == MethodKind.ExplicitInterfaceImplementation)
                {
                    diagnostics.Add(ErrorCode.ERR_PartialMethodNotExplicit, location);
                }

                if (!ContainingType.IsPartial() || ContainingType.IsInterface)
                {
                    diagnostics.Add(ErrorCode.ERR_PartialMethodOnlyInPartialClass, location);
                }
            }

            if (!IsPartial)
            {
                LazyAsyncMethodChecks(CancellationToken.None);
                Debug.Assert(state.HasComplete(CompletionPart.FinishAsyncMethodChecks));
            }

            // The runtime will not treat this method as an override or implementation of another
            // method unless both the signatures and the custom modifiers match.  Hence, in the
            // case of overrides and *explicit* implementations, we need to copy the custom modifiers
            // that are in the signature of the overridden/implemented method.  (From source, we know
            // that there can only be one such method, so there are no conflicts.)  This is
            // unnecessary for implicit implementations because, if the custom modifiers don't match,
            // we'll insert a bridge method (an explicit implementation that delegates to the implicit
            // implementation) with the correct custom modifiers
            // (see SourceNamedTypeSymbol.ImplementInterfaceMember).

            // Note: we're checking if the syntax indicates explicit implementation rather,
            // than if explicitInterfaceType is null because we don't want to look for an
            // overridden property if this is supposed to be an explicit implementation.
            if (syntax.ExplicitInterfaceSpecifier == null)
            {
                Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                // This value may not be correct, but we need something while we compute this.OverriddenMethod.
                // May be re-assigned below.
                Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault);
                Debug.Assert(_lazyCountOfCustomModifiersPrecedingByRef == 0);
                _lazyReturnTypeCustomModifiers            = ImmutableArray <CustomModifier> .Empty;
                _lazyCountOfCustomModifiersPrecedingByRef = 0;

                // If this method is an override, we may need to copy custom modifiers from
                // the overridden method (so that the runtime will recognize it as an override).
                // We check for this case here, while we can still modify the parameters and
                // return type without losing the appearance of immutability.
                if (this.IsOverride)
                {
                    // This computation will necessarily be performed with partially incomplete
                    // information.  There is no way we can determine the complete signature
                    // (i.e. including custom modifiers) until we have found the method that
                    // this method overrides.  To accommodate this, MethodSymbol.OverriddenOrHiddenMembers
                    // is written to allow relaxed matching of custom modifiers for source methods,
                    // on the assumption that they will be updated appropriately.
                    MethodSymbol overriddenMethod = this.OverriddenMethod;

                    if ((object)overriddenMethod != null)
                    {
                        CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
                                                                      out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef,
                                                                      out _lazyParameters, alsoCopyParamsModifier: true);
                    }
                }
            }
            else if ((object)_explicitInterfaceType != null)
            {
                //do this last so that it can assume the method symbol is constructed (except for ExplicitInterfaceImplementation)
                MethodSymbol implementedMethod = this.FindExplicitlyImplementedMethod(_explicitInterfaceType, syntax.Identifier.ValueText, syntax.ExplicitInterfaceSpecifier, diagnostics);

                if ((object)implementedMethod != null)
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray.Create <MethodSymbol>(implementedMethod);

                    CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType,
                                                                  out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef,
                                                                  out _lazyParameters, alsoCopyParamsModifier: false);
                }
                else
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                    Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault);
                    Debug.Assert(_lazyCountOfCustomModifiersPrecedingByRef == 0);
                    _lazyReturnTypeCustomModifiers            = ImmutableArray <CustomModifier> .Empty;
                    _lazyCountOfCustomModifiersPrecedingByRef = 0;
                }
            }

            CheckModifiers(location, diagnostics);
        }
Example #14
0
 internal static MemberSymbol Get(WellKnownMembers kind)
 {
     Debug.Assert(WellKnownMemberSymbols != null);
     return(WellKnownMemberSymbols[(int)kind]);
 }