Exemple #1
0
        private SourceEventFieldSymbol MakeAssociatedField(VariableDeclarationSyntax declaratorSyntax)
        {
            DiagnosticBag discardedDiagnostics = DiagnosticBag.GetInstance();
            var           field = new SourceEventFieldSymbol(this, declaratorSyntax, discardedDiagnostics);

            discardedDiagnostics.Free();

            Debug.Assert(field.Name == _name);
            return(field);
        }
Exemple #2
0
        internal SourceFieldLikeEventSymbol(SourceMemberContainerTypeSymbol containingType, Binder binder, SyntaxTokenList modifiers, VariableDeclarationSyntax declaratorSyntax, DiagnosticBag diagnostics)
            : base(containingType, declaratorSyntax, modifiers, null, declaratorSyntax.Identifier, 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)
                {
                    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))
            {
                _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]);
            }

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

            // Don't report these diagnostics for every declarator in this declaration.
            diagnostics.AddRange(declaratorDiagnostics);

            declaratorDiagnostics.Free();
        }