Пример #1
0
 public SignatureOnlyMethodSymbol(
     string name,
     TypeSymbol containingType,
     MethodKind methodKind,
     Cci.CallingConvention callingConvention,
     ImmutableArray <TypeParameterSymbol> typeParameters,
     ImmutableArray <ParameterSymbol> parameters,
     RefKind refKind,
     bool isInitOnly,
     TypeWithAnnotations returnType,
     ImmutableArray <CustomModifier> refCustomModifiers,
     ImmutableArray <MethodSymbol> explicitInterfaceImplementations)
 {
     Debug.Assert(returnType.IsDefault || isInitOnly == CustomModifierUtils.HasIsExternalInitModifier(returnType.CustomModifiers));
     _callingConvention  = callingConvention;
     _typeParameters     = typeParameters;
     _refKind            = refKind;
     _isInitOnly         = isInitOnly;
     _returnType         = returnType;
     _refCustomModifiers = refCustomModifiers;
     _parameters         = parameters;
     _explicitInterfaceImplementations = explicitInterfaceImplementations.NullToEmpty();
     _containingType = containingType;
     _methodKind     = methodKind;
     _name           = name;
 }
Пример #2
0
        internal SourceParameterSymbol WithCustomModifiersAndParamsCore(TypeSymbol newType, ImmutableArray <CustomModifier> newCustomModifiers, ushort countOfCustomModifiersPrecedingByRef, bool newIsParams)
        {
            newType = CustomModifierUtils.CopyTypeCustomModifiers(newType, this.Type, _refKind, this.ContainingAssembly);

            if (newCustomModifiers.IsDefaultOrEmpty)
            {
                return(new SourceComplexParameterSymbol(
                           this.ContainingSymbol,
                           this.Ordinal,
                           newType,
                           _refKind,
                           _name,
                           _locations,
                           this.SyntaxReference,
                           this.ExplicitDefaultConstantValue,
                           newIsParams,
                           this.IsExtensionMethodThis));
            }

            return(new SourceComplexParameterSymbolWithCustomModifiers(
                       this.ContainingSymbol,
                       this.Ordinal,
                       newType,
                       _refKind,
                       newCustomModifiers,
                       countOfCustomModifiersPrecedingByRef,
                       _name,
                       _locations,
                       this.SyntaxReference,
                       this.ExplicitDefaultConstantValue,
                       newIsParams,
                       this.IsExtensionMethodThis));
        }
        protected override void MethodChecks(DiagnosticBag diagnostics)
        {
            // These values may not be final, but we need to have something set here in the
            // event that we need to find the overridden accessor.
            _lazyParameters = ComputeParameters(diagnostics);
            _lazyReturnType = ComputeReturnType(diagnostics);
            _lazyReturnTypeCustomModifiers = ImmutableArray <CustomModifier> .Empty;

            if (_explicitInterfaceImplementations.Length > 0)
            {
                Debug.Assert(_explicitInterfaceImplementations.Length == 1);
                MethodSymbol implementedMethod = _explicitInterfaceImplementations[0];
                CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType, out _lazyReturnTypeCustomModifiers, out _lazyParameters, alsoCopyParamsModifier: false);
            }
            else if (this.IsOverride)
            {
                // This will cause another call to SourceMethodSymbol.LazyMethodChecks,
                // but that method already handles reentrancy for exactly this case.
                MethodSymbol overriddenMethod = this.OverriddenMethod;
                if ((object)overriddenMethod != null)
                {
                    CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType, out _lazyReturnTypeCustomModifiers, out _lazyParameters, alsoCopyParamsModifier: true);
                }
            }
            else if (_lazyReturnType.SpecialType != SpecialType.System_Void)
            {
                PropertySymbol associatedProperty = _property;
                _lazyReturnType = CustomModifierUtils.CopyTypeCustomModifiers(associatedProperty.Type, _lazyReturnType, RefKind.None, this.ContainingAssembly);
                _lazyReturnTypeCustomModifiers = associatedProperty.TypeCustomModifiers;
            }
        }
        internal SourceParameterSymbol WithCustomModifiersAndParamsCore(TypeSymbol newType, ImmutableArray <CustomModifier> newCustomModifiers, ImmutableArray <CustomModifier> newRefCustomModifiers, bool newIsParams)
        {
            newType = CustomModifierUtils.CopyTypeCustomModifiers(newType, this.Type, this.ContainingAssembly);

            TypeWithAnnotations newTypeWithModifiers = this.TypeWithAnnotations.WithTypeAndModifiers(newType, newCustomModifiers);

            if (newRefCustomModifiers.IsEmpty)
            {
                return(new SourceComplexParameterSymbol(
                           this.ContainingSymbol,
                           this.Ordinal,
                           newTypeWithModifiers,
                           _refKind,
                           _name,
                           _locations,
                           this.SyntaxReference,
                           newIsParams,
                           this.IsExtensionMethodThis));
            }

            // Local functions should never have custom modifiers
            Debug.Assert(!(ContainingSymbol is LocalFunctionSymbol));

            return(new SourceComplexParameterSymbolWithCustomModifiersPrecedingByRef(
                       this.ContainingSymbol,
                       this.Ordinal,
                       newTypeWithModifiers,
                       _refKind,
                       newRefCustomModifiers,
                       _name,
                       _locations,
                       this.SyntaxReference,
                       newIsParams,
                       this.IsExtensionMethodThis));
        }
Пример #5
0
        protected static void CopyEventCustomModifiers(EventSymbol eventWithCustomModifiers, ref TypeSymbol type, AssemblySymbol containingAssembly)
        {
            Debug.Assert((object)eventWithCustomModifiers != null);

            TypeSymbol overriddenEventType = eventWithCustomModifiers.Type;

            // We do an extra check before copying the type to handle the case where the overriding
            // event (incorrectly) has a different type than the overridden event.  In such cases,
            // we want to retain the original (incorrect) type to avoid hiding the type given in source.
            if (type.Equals(overriddenEventType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreDynamic))
            {
                type = CustomModifierUtils.CopyTypeCustomModifiers(overriddenEventType, type, containingAssembly);
            }
        }
        protected override void MethodChecks(DiagnosticBag diagnostics)
        {
            // These values may not be final, but we need to have something set here in the
            // event that we need to find the overridden accessor.
            _lazyParameters      = ComputeParameters(diagnostics);
            _lazyReturnType      = ComputeReturnType(diagnostics);
            _lazyCustomModifiers = CustomModifiersTuple.Empty;

            if (_explicitInterfaceImplementations.Length > 0)
            {
                Debug.Assert(_explicitInterfaceImplementations.Length == 1);
                MethodSymbol implementedMethod = _explicitInterfaceImplementations[0];
                CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType,
                                                              out _lazyCustomModifiers,
                                                              out _lazyParameters, alsoCopyParamsModifier: false);
            }
            else if (this.IsOverride)
            {
                // This will cause another call to SourceMethodSymbol.LazyMethodChecks,
                // but that method already handles reentrancy for exactly this case.
                MethodSymbol overriddenMethod = this.OverriddenMethod;
                if ((object)overriddenMethod != null)
                {
                    CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
                                                                  out _lazyCustomModifiers,
                                                                  out _lazyParameters, alsoCopyParamsModifier: true);
                }
#if XSHARP
                /*if (this.IsVirtual)*/
                {
                    if ((object)overriddenMethod != null)
                    {
                        flags = new Flags(flags.MethodKind, flags.DeclarationModifiers & ~DeclarationModifiers.Virtual, flags.ReturnsVoid, flags.IsExtensionMethod, flags.IsMetadataVirtual(true));
                    }
                    else
                    {
                        flags = new Flags(flags.MethodKind, flags.DeclarationModifiers & ~DeclarationModifiers.Override, flags.ReturnsVoid, flags.IsExtensionMethod, flags.IsMetadataVirtual(true));
                    }
                }
#endif
            }
            else if (_lazyReturnType.SpecialType != SpecialType.System_Void)
            {
                PropertySymbol associatedProperty = _property;
                _lazyReturnType      = CustomModifierUtils.CopyTypeCustomModifiers(associatedProperty.Type, _lazyReturnType, this.ContainingAssembly);
                _lazyCustomModifiers = CustomModifiersTuple.Create(associatedProperty.TypeCustomModifiers, associatedProperty.RefCustomModifiers);
            }
        }
Пример #7
0
        protected static void CopyEventCustomModifiers(EventSymbol eventWithCustomModifiers, ref TypeSymbolWithAnnotations type, AssemblySymbol containingAssembly, Symbol nonNullTypesContext)
        {
            Debug.Assert((object)eventWithCustomModifiers != null);
            Debug.Assert(nonNullTypesContext != null);

            TypeSymbol overriddenEventType = eventWithCustomModifiers.Type.TypeSymbol;

            // We do an extra check before copying the type to handle the case where the overriding
            // event (incorrectly) has a different type than the overridden event.  In such cases,
            // we want to retain the original (incorrect) type to avoid hiding the type given in source.
            if (type.TypeSymbol.Equals(overriddenEventType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes | TypeCompareKind.IgnoreDynamic))
            {
                type = type.WithTypeAndModifiers(CustomModifierUtils.CopyTypeCustomModifiers(overriddenEventType, type.TypeSymbol, containingAssembly, nonNullTypesContext),
                                                 eventWithCustomModifiers.Type.CustomModifiers);
            }
        }
        internal SourceParameterSymbol WithCustomModifiersAndParamsCore(TypeSymbol newType, ImmutableArray <CustomModifier> newCustomModifiers, bool hasByRefBeforeCustomModifiers, bool newIsParams)
        {
            newType = CustomModifierUtils.CopyTypeCustomModifiers(newType, this.Type, this.refKind, this.ContainingAssembly);

            return(new SourceComplexParameterSymbol(
                       this.ContainingSymbol,
                       this.Ordinal,
                       newType,
                       this.refKind,
                       newCustomModifiers,
                       hasByRefBeforeCustomModifiers,
                       this.name,
                       this.locations,
                       this.SyntaxReference,
                       this.ExplicitDefaultConstantValue,
                       newIsParams,
                       this.IsExtensionMethodThis));
        }
Пример #9
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);
        }
        protected MethodSymbol?MethodChecks(TypeWithAnnotations returnType, ImmutableArray <ParameterSymbol> parameters, BindingDiagnosticBag diagnostics)
        {
            _lazyReturnType = returnType;
            _lazyParameters = parameters;

            // set ReturnsVoid flag
            this.SetReturnsVoid(_lazyReturnType.IsVoidType());

            this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);
            this.CheckFileTypeUsage(_lazyReturnType, _lazyParameters, diagnostics);

            var location = locations[0];

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

            ExtensionMethodChecks(diagnostics);

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

                if (!ContainingType.IsPartial())
                {
                    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 SourceMemberContainerTypeSymbol.SynthesizeInterfaceMemberImplementation).

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

            MethodSymbol?overriddenOrExplicitlyImplementedMethod = null;

            // 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 (MethodKind != MethodKind.ExplicitInterfaceImplementation)
            {
                Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                // 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.
                    overriddenOrExplicitlyImplementedMethod = this.OverriddenMethod;

                    if ((object)overriddenOrExplicitlyImplementedMethod != null)
                    {
                        CustomModifierUtils.CopyMethodCustomModifiers(overriddenOrExplicitlyImplementedMethod, this, out _lazyReturnType,
                                                                      out _lazyRefCustomModifiers,
                                                                      out _lazyParameters, alsoCopyParamsModifier: true);
                    }
                }
                else if (RefKind == RefKind.RefReadOnly)
                {
                    var modifierType = Binder.GetWellKnownType(DeclaringCompilation, WellKnownType.System_Runtime_InteropServices_InAttribute, diagnostics, ReturnTypeLocation);

                    _lazyRefCustomModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateRequired(modifierType));
                }
            }
            else if (ExplicitInterfaceType is not null)
            {
                //do this last so that it can assume the method symbol is constructed (except for ExplicitInterfaceImplementation)
                overriddenOrExplicitlyImplementedMethod = FindExplicitlyImplementedMethod(diagnostics);

                if (overriddenOrExplicitlyImplementedMethod is not null)
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray.Create <MethodSymbol>(overriddenOrExplicitlyImplementedMethod);

                    CustomModifierUtils.CopyMethodCustomModifiers(overriddenOrExplicitlyImplementedMethod, this, out _lazyReturnType,
                                                                  out _lazyRefCustomModifiers,
                                                                  out _lazyParameters, alsoCopyParamsModifier: false);
                    this.FindExplicitlyImplementedMemberVerification(overriddenOrExplicitlyImplementedMethod, diagnostics);
                    TypeSymbol.CheckNullableReferenceTypeAndScopedMismatchOnImplementingMember(this.ContainingType, this, overriddenOrExplicitlyImplementedMethod, isExplicit: true, diagnostics);
                }
                else
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                    Debug.Assert(_lazyReturnType.CustomModifiers.IsEmpty);
                }
            }

            return(overriddenOrExplicitlyImplementedMethod);
        }
Пример #11
0
        internal MethodSymbol validateMethod(MethodSymbol overriddenMethod, DiagnosticBag diagnostics, Location location)
        {
            if ((object)overriddenMethod != null)
            {
                if (this.HasClipperCallingConvention() != overriddenMethod.HasClipperCallingConvention())
                {
                    if (this.HasClipperCallingConvention())
                    {
                        diagnostics.Add(ErrorCode.ERR_ClipperInSubClass, location, this.Name);
                    }
                    else
                    {
                        diagnostics.Add(ErrorCode.ERR_ClipperInParentClass, location, this.Name);
                    }
                    overriddenMethod = null;
                }
            }
            else if (XSharpString.CaseSensitive && !this.DeclarationModifiers.HasFlag(DeclarationModifiers.New) &&
                     (this.DeclarationModifiers.HasFlag(DeclarationModifiers.Virtual) || this.DeclarationModifiers.HasFlag(DeclarationModifiers.Override)))
            {
                // check if we have a base type and if the base type has a method with the same name but different casing
                var baseType = this.ContainingType.BaseTypeNoUseSiteDiagnostics;
                var members  = baseType.GetMembersUnordered().Where(member =>
                                                                    member.Kind == SymbolKind.Method && member.IsVirtual && String.Equals(member.Name, this.Name, StringComparison.OrdinalIgnoreCase));
                if (members.Count() > 0)
                {
                    foreach (var member in members)
                    {
                        var  metSym         = member as MethodSymbol;
                        bool equalSignature = metSym.ParameterCount == this.ParameterCount && this.ReturnType == metSym.ReturnType;
                        if (equalSignature)
                        {
                            var thisTypes  = this.ParameterTypes;
                            var theirTypes = metSym.ParameterTypes;
                            for (int i = 0; i < thisTypes.Length; i++)
                            {
                                if (thisTypes[i] != theirTypes[i])
                                {
                                    equalSignature = false;
                                    break;
                                }
                            }
                        }
                        if (equalSignature)
                        {
                            diagnostics.Add(ErrorCode.ERR_CaseDifference, location, baseType.Name, "method", member.Name, this.Name);
                        }
                    }
                }
            }
            if ((object)overriddenMethod != null)
            {
                _overrideState = 2;  // checked and has a (correct) override
            }
            else
            {
                _overrideState = 1; // checked and does not have an override
            }
            if ((object)overriddenMethod != null)
            {
                CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
                                                              out _lazyCustomModifiers,
                                                              out _lazyParameters, alsoCopyParamsModifier: true);
            }
            var node = this.SyntaxNode.Green as Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.MethodDeclarationSyntax;
            var mods = flags.DeclarationModifiers;

            if ((object)overriddenMethod != null)
            {
                if (this.Name != overriddenMethod.Name)
                {
                    this._name = overriddenMethod.Name;
                }
                // remove generated Virtual Modifiers
                foreach (var token in node.Modifiers)
                {
                    if (token.Kind == SyntaxKind.VirtualKeyword && token.XGenerated)
                    {
                        mods = mods & ~DeclarationModifiers.Virtual;
                    }
                }

                flags = new Flags(flags.MethodKind, mods, flags.ReturnsVoid, flags.IsExtensionMethod, flags.IsMetadataVirtual(true));
            }
            else
            {
                // remove generated Override Modifiers
                foreach (var token in node.Modifiers)
                {
                    if (token.Kind == SyntaxKind.OverrideKeyword && token.XGenerated)
                    {
                        mods = mods & ~DeclarationModifiers.Override;
                    }
                }
                flags = new Flags(flags.MethodKind, mods, flags.ReturnsVoid, flags.IsExtensionMethod, flags.IsMetadataVirtual(true));
            }

            return(overriddenMethod);
        }