コード例 #1
0
        private SourceEventFieldSymbol MakeAssociatedField(VariableDeclaratorSyntax declaratorSyntax)
        {
            var field = new SourceEventFieldSymbol(this, declaratorSyntax, BindingDiagnosticBag.Discarded);

            Debug.Assert(field.Name == _name);
            return(field);
        }
コード例 #2
0
        private SourceEventFieldSymbol MakeAssociatedField(VariableDeclaratorSyntax declaratorSyntax)
        {
            DiagnosticBag discardedDiagnostics = DiagnosticBag.GetInstance();
            var           field = new SourceEventFieldSymbol(this, declaratorSyntax, discardedDiagnostics);

            discardedDiagnostics.Free();

            Debug.Assert(field.Name == _name);
            return(field);
        }
コード例 #3
0
        private SourceEventFieldSymbol MakeAssociatedField(VariableDeclaratorSyntax declaratorSyntax)
        {
            DiagnosticBag discardedDiagnostics = DiagnosticBag.GetInstance();
            var           field = new SourceEventFieldSymbol(this, declaratorSyntax, discardedDiagnostics);

            discardedDiagnostics.Free();

#if XSHARP
            Debug.Assert(XSharpString.Equals(field.Name, _name));
#else
            Debug.Assert(field.Name == _name);
#endif
            return(field);
        }
コード例 #4
0
        internal SourceFieldLikeEventSymbol(SourceMemberContainerTypeSymbol containingType, Binder binder, SyntaxTokenList modifiers, VariableDeclaratorSyntax declaratorSyntax, DiagnosticBag diagnostics)
            : base(containingType, declaratorSyntax, modifiers, isFieldLike: true, interfaceSpecifierSyntaxOpt: null,
                   nameTokenSyntax: declaratorSyntax.Identifier, diagnostics: diagnostics)
        {
            _name = declaratorSyntax.Identifier.ValueText;

            var declaratorDiagnostics = DiagnosticBag.GetInstance();
            var declarationSyntax     = (VariableDeclarationSyntax)declaratorSyntax.Parent;

            _type = BindEventType(binder, declarationSyntax.Type, declaratorDiagnostics);

            // The runtime will not treat the accessors of this event as overrides or implementations
            // of those of another event unless both the signatures and the custom modifiers match.
            // Hence, in the case of overrides and *explicit* implementations (not possible for field-like
            // events), we need to copy the custom modifiers that are in the signatures of the
            // overridden/implemented event accessors. (From source, we know that there can only be one
            // overridden/implemented event, so there are no conflicts.)  This is unnecessary for implicit
            // implementations because, if the custom modifiers don't match, we'll insert bridge methods
            // for the accessors (explicit implementations that delegate to the implicit implementations)
            // with the correct custom modifiers (see SourceMemberContainerTypeSymbol.SynthesizeInterfaceMemberImplementation).

            // If this event is an override, we may need to copy custom modifiers from
            // the overridden event (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)
            {
                EventSymbol overriddenEvent = this.OverriddenEvent;
                if ((object)overriddenEvent != null)
                {
                    CopyEventCustomModifiers(overriddenEvent, ref _type, ContainingAssembly);
                }
            }

            bool hasInitializer  = declaratorSyntax.Initializer != null;
            bool inInterfaceType = containingType.IsInterfaceType();

            if (hasInitializer)
            {
                if (inInterfaceType && !this.IsStatic)
                {
                    diagnostics.Add(ErrorCode.ERR_InterfaceEventInitializer, this.Locations[0], this);
                }
                else if (this.IsAbstract)
                {
                    diagnostics.Add(ErrorCode.ERR_AbstractEventInitializer, this.Locations[0], this);
                }
            }

            // NOTE: if there's an initializer in source, we'd better create a backing field, regardless of
            // whether or not the initializer is legal.
            if (hasInitializer || !(this.IsExtern || this.IsAbstract))
            {
                _associatedField = MakeAssociatedField(declaratorSyntax);
                // Don't initialize this.type - we'll just use the type of the field (which is lazy and handles var)
            }

            if (!IsStatic && ContainingType.IsReadOnly)
            {
                diagnostics.Add(ErrorCode.ERR_FieldlikeEventsInRoStruct, this.Locations[0]);
            }

            if (inInterfaceType)
            {
                if (this.IsExtern || this.IsStatic)
                {
                    if (!ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation)
                    {
                        diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, this.Locations[0]);
                    }
                }
                else if (!this.IsAbstract)
                {
                    diagnostics.Add(ErrorCode.ERR_EventNeedsBothAccessors, this.Locations[0], this);
                }
            }

            // Accessors will assume that Type is available.
            _addMethod    = new SynthesizedFieldLikeEventAccessorSymbol(this, isAdder: true);
            _removeMethod = new SynthesizedFieldLikeEventAccessorSymbol(this, isAdder: false);

            if (declarationSyntax.Variables[0] == declaratorSyntax)
            {
                // Don't report these diagnostics for every declarator in this declaration.
                diagnostics.AddRange(declaratorDiagnostics);
            }

            declaratorDiagnostics.Free();
        }
        internal SourceFieldLikeEventSymbol(SourceMemberContainerTypeSymbol containingType, Binder binder, SyntaxTokenList modifiers, VariableDeclaratorSyntax declaratorSyntax, DiagnosticBag diagnostics)
            : base(containingType, declaratorSyntax, modifiers, null, declaratorSyntax.Identifier, diagnostics)
        {
            this.name = declaratorSyntax.Identifier.ValueText;


            var declaratorDiagnostics = DiagnosticBag.GetInstance();
            var declarationSyntax = (VariableDeclarationSyntax)declaratorSyntax.Parent;
            this.type = BindEventType(binder, declarationSyntax.Type, declaratorDiagnostics);

            // The runtime will not treat the accessors of this event as overrides or implementations
            // of those of another event unless both the signatures and the custom modifiers match.
            // Hence, in the case of overrides and *explicit* implementations (not possible for field-like
            // events), we need to copy the custom modifiers that are in the signatures of the 
            // overridden/implemented event accessors. (From source, we know that there can only be one 
            // overridden/implemented event, so there are no conflicts.)  This is unnecessary for implicit 
            // implementations because, if the custom modifiers don't match, we'll insert bridge methods 
            // for the accessors (explicit implementations that delegate to the implicit implementations) 
            // with the correct custom modifiers (see SourceNamedTypeSymbol.ImplementInterfaceMember).

            // If this event is an override, we may need to copy custom modifiers from
            // the overridden event (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)
            {
                EventSymbol overriddenEvent = this.OverriddenEvent;
                if ((object)overriddenEvent != null)
                {
                    CopyEventCustomModifiers(overriddenEvent, ref this.type);
                }
            }

            bool hasInitializer = declaratorSyntax.Initializer != null;
            bool inInterfaceType = containingType.IsInterfaceType();

            if (hasInitializer)
            {
                if (inInterfaceType)
                {
                    diagnostics.Add(ErrorCode.ERR_InterfaceEventInitializer, this.Locations[0], this);
                }
                else if (this.IsAbstract)
                {
                    diagnostics.Add(ErrorCode.ERR_AbstractEventInitializer, this.Locations[0], this);
                }
            }

            // NOTE: if there's an initializer in source, we'd better create a backing field, regardless of
            // whether or not the initializer is legal.
            if (hasInitializer || !(inInterfaceType || this.IsExtern || this.IsAbstract))
            {
                this.associatedField = MakeAssociatedField(declaratorSyntax);
                // Don't initialize this.type - we'll just use the type of the field (which is lazy and handles var)
            }

            // Accessors will assume that Type is available.
            this.addMethod = new SynthesizedFieldLikeEventAccessorSymbol(this, isAdder: true);
            this.removeMethod = new SynthesizedFieldLikeEventAccessorSymbol(this, isAdder: false);

            if (declarationSyntax.Variables[0] == declaratorSyntax)
            {
                // Don't report these diagnostics for every declarator in this declaration.
                diagnostics.AddRange(declaratorDiagnostics);
            }

            declaratorDiagnostics.Free();
        }
        private SourceEventFieldSymbol MakeAssociatedField(VariableDeclaratorSyntax declaratorSyntax)
        {
            DiagnosticBag discardedDiagnostics = DiagnosticBag.GetInstance();
            var field = new SourceEventFieldSymbol(this, declaratorSyntax, discardedDiagnostics);
            discardedDiagnostics.Free();

            Debug.Assert(field.Name == this.name);
            return field;
        }