Ejemplo n.º 1
0
        internal SynthesizedStateMachineProperty(
            MethodSymbol interfacePropertyGetter,
            StateMachineTypeSymbol stateMachineType)
        {
            _name = ExplicitInterfaceHelpers.GetMemberName(interfacePropertyGetter.AssociatedSymbol.Name, interfacePropertyGetter.ContainingType, aliasQualifierOpt: null);
            var getterName = ExplicitInterfaceHelpers.GetMemberName(interfacePropertyGetter.Name, interfacePropertyGetter.ContainingType, aliasQualifierOpt: null);

            _getter = new SynthesizedStateMachineDebuggerHiddenMethod(
                getterName,
                interfacePropertyGetter,
                stateMachineType,
                associatedProperty: this,
                hasMethodBodyDependency: false);
        }
        public static SourcePropertyAccessorSymbol CreateAccessorSymbol(
            NamedTypeSymbol containingType,
            SourcePropertySymbol property,
            DeclarationModifiers propertyModifiers,
            string propertyName,
            AccessorDeclarationSyntax syntax,
            PropertySymbol explicitlyImplementedPropertyOpt,
            string aliasQualifierOpt,
            bool isAutoPropertyAccessor,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(syntax.Kind == SyntaxKind.GetAccessorDeclaration || syntax.Kind == SyntaxKind.SetAccessorDeclaration);

            bool   isGetMethod = (syntax.Kind == SyntaxKind.GetAccessorDeclaration);
            bool   isWinMd     = property.IsCompilationOutputWinMdObj();
            string name;
            ImmutableArray <MethodSymbol> explicitInterfaceImplementations;

            if ((object)explicitlyImplementedPropertyOpt == null)
            {
                name = GetAccessorName(propertyName, isGetMethod, isWinMd);
                explicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;
            }
            else
            {
                MethodSymbol implementedAccessor = isGetMethod ? explicitlyImplementedPropertyOpt.GetMethod : explicitlyImplementedPropertyOpt.SetMethod;
                string       accessorName        = (object)implementedAccessor != null ? implementedAccessor.Name
                    : GetAccessorName(explicitlyImplementedPropertyOpt.MetadataName, isGetMethod, isWinMd); //Not name - could be indexer placeholder
                name = ExplicitInterfaceHelpers.GetMemberName(accessorName, explicitlyImplementedPropertyOpt.ContainingType, aliasQualifierOpt);
                explicitInterfaceImplementations =
                    (object)implementedAccessor == null ?
                    ImmutableArray <MethodSymbol> .Empty :
                    ImmutableArray.Create <MethodSymbol>(implementedAccessor);
            }

            var methodKind = isGetMethod ? MethodKind.PropertyGet : MethodKind.PropertySet;

            return(new SourcePropertyAccessorSymbol(
                       containingType,
                       name,
                       property,
                       propertyModifiers,
                       explicitInterfaceImplementations,
                       syntax.Keyword.GetLocation(),
                       syntax,
                       methodKind,
                       isAutoPropertyAccessor,
                       diagnostics));
        }
Ejemplo n.º 3
0
        internal SynthesizedImplementationReadOnlyProperty(
            MethodSymbol interfaceMethod,
            NamedTypeSymbol implementingType,
            bool debuggerHidden = false)
        {
            this.propName = ExplicitInterfaceHelpers.GetMemberName(interfaceMethod.AssociatedSymbol.Name, interfaceMethod.ContainingType, aliasQualifierOpt: null);

            var getterName = ExplicitInterfaceHelpers.GetMemberName(interfaceMethod.Name, interfaceMethod.ContainingType, aliasQualifierOpt: null);

            getter = new SynthesizedImplementationMethod(interfaceMethod,
                                                         implementingType,
                                                         getterName,
                                                         debuggerHidden,
                                                         associatedProperty: this);
        }
Ejemplo n.º 4
0
        internal SynthesizedStateMachineProperty(
            MethodSymbol interfacePropertyGetter,
            StateMachineTypeSymbol stateMachineType,
            bool debuggerHidden,
            bool hasMethodBodyDependency)
        {
            this.name = ExplicitInterfaceHelpers.GetMemberName(interfacePropertyGetter.AssociatedSymbol.Name, interfacePropertyGetter.ContainingType, aliasQualifierOpt: null);
            var getterName = ExplicitInterfaceHelpers.GetMemberName(interfacePropertyGetter.Name, interfacePropertyGetter.ContainingType, aliasQualifierOpt: null);

            this.getter = new SynthesizedStateMachineMethod(
                getterName,
                interfacePropertyGetter,
                stateMachineType,
                associatedProperty: this,
                debuggerHidden: debuggerHidden,
                generateDebugInfo: !debuggerHidden,
                hasMethodBodyDependency: hasMethodBodyDependency);
        }
        internal SynthesizedStateMachineProperty(
            MethodSymbol interfacePropertyGetter,
            NamedTypeSymbol implementingType,
            bool debuggerHidden,
            bool hasMethodBodyDependency)
        {
            this.name = ExplicitInterfaceHelpers.GetMemberName(interfacePropertyGetter.AssociatedSymbol.Name, interfacePropertyGetter.ContainingType, aliasQualifierOpt: null);
            var getterName = ExplicitInterfaceHelpers.GetMemberName(interfacePropertyGetter.Name, interfacePropertyGetter.ContainingType, aliasQualifierOpt: null);

            getter = new SynthesizedStateMachineMethod(
                getterName,
                interfacePropertyGetter,
                implementingType,
                asyncKickoffMethod: null,
                associatedProperty: this,
                debuggerHidden: debuggerHidden,
                hasMethodBodyDependency: hasMethodBodyDependency);
        }
        public SourceEventAccessorSymbol(
            SourceEventSymbol @event,
            SyntaxReference syntaxReference,
            ImmutableArray <Location> locations,
            EventSymbol explicitlyImplementedEventOpt,
            string aliasQualifierOpt,
            bool isAdder,
            bool isIterator,
            bool isNullableAnalysisEnabled)
            : base(@event.containingType, syntaxReference, locations, isIterator)
        {
            _event = @event;

            string name;
            ImmutableArray <MethodSymbol> explicitInterfaceImplementations;

            if ((object)explicitlyImplementedEventOpt == null)
            {
                name = SourceEventSymbol.GetAccessorName(@event.Name, isAdder);
                explicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;
            }
            else
            {
                MethodSymbol implementedAccessor = isAdder ? explicitlyImplementedEventOpt.AddMethod : explicitlyImplementedEventOpt.RemoveMethod;
                string       accessorName        = (object)implementedAccessor != null ? implementedAccessor.Name : SourceEventSymbol.GetAccessorName(explicitlyImplementedEventOpt.Name, isAdder);

                name = ExplicitInterfaceHelpers.GetMemberName(accessorName, explicitlyImplementedEventOpt.ContainingType, aliasQualifierOpt);
                explicitInterfaceImplementations = (object)implementedAccessor == null ? ImmutableArray <MethodSymbol> .Empty : ImmutableArray.Create <MethodSymbol>(implementedAccessor);
            }

            _explicitInterfaceImplementations = explicitInterfaceImplementations;

            this.MakeFlags(
                isAdder ? MethodKind.EventAdd : MethodKind.EventRemove,
                @event.Modifiers,
                returnsVoid: false, // until we learn otherwise (in LazyMethodChecks).
                isExtensionMethod: false,
                isNullableAnalysisEnabled: isNullableAnalysisEnabled,
                isMetadataVirtualIgnoringModifiers: @event.IsExplicitInterfaceImplementation && (@event.Modifiers & DeclarationModifiers.Static) == 0);

            _name = GetOverriddenAccessorName(@event, isAdder) ?? name;
        }
        public static SourceOrdinaryMethodSymbol CreateMethodSymbol(
            NamedTypeSymbol containingType,
            Binder bodyBinder,
            MethodDeclarationSyntax syntax,
            DiagnosticBag diagnostics)
        {
            var interfaceSpecifier = syntax.ExplicitInterfaceSpecifier;
            var nameToken          = syntax.Identifier;

            TypeSymbol explicitInterfaceType;
            string     discardedAliasQualifier;
            var        name     = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(bodyBinder, interfaceSpecifier, nameToken.ValueText, diagnostics, out explicitInterfaceType, out discardedAliasQualifier);
            var        location = new SourceLocation(nameToken);

            var methodKind = interfaceSpecifier == null
                ? MethodKind.Ordinary
                : MethodKind.ExplicitInterfaceImplementation;

            return(new SourceOrdinaryMethodSymbol(containingType, explicitInterfaceType, name, location, syntax, methodKind, diagnostics));
        }
Ejemplo n.º 8
0
        public int GetHashCode(Symbol member)
        {
            int hash = 1;

            if ((object)member != null)
            {
                hash = Hash.Combine((int)member.Kind, hash);

                if (_considerName)
                {
#if XSHARP
                    hash = Hash.Combine(ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(member.Name).ToUpper(), hash); // CaseInsensitive
#else
                    hash = Hash.Combine(ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(member.Name), hash);
#endif
                    // CONSIDER: could use interface type, but that might be quite expensive
                }

                if (_considerReturnType)
                {
                    RefKind    refKind;
                    TypeSymbol returnType;
                    ImmutableArray <CustomModifier> customModifiers_Ignored;
                    member.GetTypeOrReturnType(out refKind, out returnType, out customModifiers_Ignored, out customModifiers_Ignored);

                    hash = Hash.Combine((int)refKind, hash);

                    if (member.GetMemberArity() == 0 && !_considerCustomModifiers) // If it is generic, then type argument might be in return type.
                    {
                        hash = Hash.Combine(returnType, hash);
                    }
                }

                // CONSIDER: modify hash for constraints?

                hash = Hash.Combine(member.GetMemberArity(), hash);
                hash = Hash.Combine(member.GetParameterCount(), hash);
            }
            return(hash);
        }
        public static SourceUserDefinedOperatorSymbol CreateUserDefinedOperatorSymbol(
            SourceMemberContainerTypeSymbol containingType,
            Binder bodyBinder,
            OperatorDeclarationSyntax syntax,
            bool isNullableAnalysisEnabled,
            BindingDiagnosticBag diagnostics)
        {
            var location = syntax.OperatorToken.GetLocation();

            string name = OperatorFacts.OperatorNameFromDeclaration(syntax);

            if (SyntaxFacts.IsCheckedOperator(name))
            {
                MessageID.IDS_FeatureCheckedUserDefinedOperators.CheckFeatureAvailability(diagnostics, syntax, syntax.CheckedKeyword.GetLocation());
            }
            else if (!syntax.OperatorToken.IsMissing && syntax.CheckedKeyword.IsKind(SyntaxKind.CheckedKeyword))
            {
                diagnostics.Add(ErrorCode.ERR_OperatorCantBeChecked, syntax.CheckedKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxFacts.GetOperatorKind(name)));
            }

            if (name == WellKnownMemberNames.UnsignedRightShiftOperatorName)
            {
                MessageID.IDS_FeatureUnsignedRightShift.CheckFeatureAvailability(diagnostics, syntax, syntax.OperatorToken.GetLocation());
            }

            var interfaceSpecifier = syntax.ExplicitInterfaceSpecifier;

            TypeSymbol explicitInterfaceType;

            name = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(bodyBinder, interfaceSpecifier, name, diagnostics, out explicitInterfaceType, aliasQualifierOpt: out _);

            var methodKind = interfaceSpecifier == null
                ? MethodKind.UserDefinedOperator
                : MethodKind.ExplicitInterfaceImplementation;

            return(new SourceUserDefinedOperatorSymbol(
                       methodKind, containingType, explicitInterfaceType, name, location, syntax, isNullableAnalysisEnabled, diagnostics));
        }
Ejemplo n.º 10
0
        public int GetHashCode(Symbol member)
        {
            int hash = 1;

            if ((object)member != null)
            {
                hash = Hash.Combine((int)member.Kind, hash);

                if (_considerName)
                {
                    hash = Hash.Combine(ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(member.Name), hash);
                    // CONSIDER: could use interface type, but that might be quite expensive
                }

                if (_considerReturnType)
                {
                    RefKind    refKind;
                    TypeSymbol returnType;
                    ImmutableArray <CustomModifier> returnTypeCustomModifiers;
                    ushort countOfCustomModifiersPrecedingByRef;
                    member.GetTypeOrReturnType(out refKind, out returnType, out returnTypeCustomModifiers, out countOfCustomModifiersPrecedingByRef);

                    hash = Hash.Combine((int)refKind, hash);

                    if (member.GetMemberArity() == 0 && !_considerCustomModifiers) // If it is generic, then type argument might be in return type.
                    {
                        hash = Hash.Combine(returnType, hash);
                    }
                }

                // CONSIDER: modify hash for constraints?

                hash = Hash.Combine(member.GetMemberArity(), hash);
                hash = Hash.Combine(member.GetParameterCount(), hash);
            }
            return(hash);
        }
Ejemplo n.º 11
0
        public static SourceUserDefinedOperatorSymbol CreateUserDefinedOperatorSymbol(
            SourceMemberContainerTypeSymbol containingType,
            Binder bodyBinder,
            OperatorDeclarationSyntax syntax,
            bool isNullableAnalysisEnabled,
            BindingDiagnosticBag diagnostics)
        {
            var location = syntax.OperatorToken.GetLocation();

            string name = OperatorFacts.OperatorNameFromDeclaration(syntax);

            var interfaceSpecifier = syntax.ExplicitInterfaceSpecifier;

            TypeSymbol explicitInterfaceType;

            name = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(bodyBinder, interfaceSpecifier, name, diagnostics, out explicitInterfaceType, aliasQualifierOpt: out _);

            var methodKind = interfaceSpecifier == null
                ? MethodKind.UserDefinedOperator
                : MethodKind.ExplicitInterfaceImplementation;

            return(new SourceUserDefinedOperatorSymbol(
                       methodKind, containingType, explicitInterfaceType, name, location, syntax, isNullableAnalysisEnabled, diagnostics));
        }
        public SynthesizedImplementationMethod(
            MethodSymbol interfaceMethod,
            NamedTypeSymbol implementingType,
            string name                       = null,
            bool generateDebugInfo            = true,
            PropertySymbol associatedProperty = null)
        {
            //it does not make sense to add methods to substituted types
            Debug.Assert(implementingType.IsDefinition);

            _name               = name ?? ExplicitInterfaceHelpers.GetMemberName(interfaceMethod.Name, interfaceMethod.ContainingType, aliasQualifierOpt: null);
            _implementingType   = implementingType;
            _generateDebugInfo  = generateDebugInfo;
            _associatedProperty = associatedProperty;
            _explicitInterfaceImplementations = ImmutableArray.Create <MethodSymbol>(interfaceMethod);

            // alpha-rename to get the implementation's type parameters
            var typeMap = interfaceMethod.ContainingType.TypeSubstitution ?? TypeMap.Empty;

            typeMap.WithAlphaRename(interfaceMethod, this, out _typeParameters);

            _interfaceMethod = interfaceMethod.ConstructIfGeneric(_typeParameters.Cast <TypeParameterSymbol, TypeSymbol>());
            _parameters      = SynthesizedParameterSymbol.DeriveParameters(_interfaceMethod, this);
        }
Ejemplo n.º 13
0
        public int GetHashCode(Symbol member)
        {
            int hash = 1;

            if ((object)member != null)
            {
                hash = Hash.Combine((int)member.Kind, hash);

                if (_considerName)
                {
                    hash = Hash.Combine(
                        ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(member.Name),
                        hash
                        );
                    // CONSIDER: could use interface type, but that might be quite expensive
                }

                if (
                    _considerReturnType &&
                    member.GetMemberArity() == 0 &&
                    (_typeComparison & TypeCompareKind.AllIgnoreOptions) == 0
                    ) // If it is generic, then type argument might be in return type.
                {
                    hash = Hash.Combine(member.GetTypeOrReturnType().GetHashCode(), hash);
                }

                // CONSIDER: modify hash for constraints?

                if (member.Kind != SymbolKind.Field)
                {
                    hash = Hash.Combine(member.GetMemberArity(), hash);
                    hash = Hash.Combine(member.GetParameterCount(), hash);
                }
            }
            return(hash);
        }
Ejemplo n.º 14
0
        internal SourceCustomEventAccessorSymbol(
            SourceEventSymbol @event,
            AccessorDeclarationSyntax syntax,
            EventSymbol explicitlyImplementedEventOpt,
            string aliasQualifierOpt,
            DiagnosticBag diagnostics)
            : base(@event,
                   syntax.GetReference(),
                   syntax.Body.GetReferenceOrNull(),
                   ImmutableArray.Create(syntax.Keyword.GetLocation()))
        {
            Debug.Assert(syntax != null);
            Debug.Assert(syntax.Kind == SyntaxKind.AddAccessorDeclaration || syntax.Kind == SyntaxKind.RemoveAccessorDeclaration);

            bool isAdder = syntax.Kind == SyntaxKind.AddAccessorDeclaration;

            string name;
            ImmutableArray <MethodSymbol> explicitInterfaceImplementations;

            if ((object)explicitlyImplementedEventOpt == null)
            {
                name = SourceEventSymbol.GetAccessorName(@event.Name, isAdder);
                explicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;
            }
            else
            {
                MethodSymbol implementedAccessor = isAdder ? explicitlyImplementedEventOpt.AddMethod : explicitlyImplementedEventOpt.RemoveMethod;
                string       accessorName        = (object)implementedAccessor != null ? implementedAccessor.Name : SourceEventSymbol.GetAccessorName(explicitlyImplementedEventOpt.Name, isAdder);

                name = ExplicitInterfaceHelpers.GetMemberName(accessorName, explicitlyImplementedEventOpt.ContainingType, aliasQualifierOpt);
                explicitInterfaceImplementations = (object)implementedAccessor == null ? ImmutableArray <MethodSymbol> .Empty : ImmutableArray.Create <MethodSymbol>(implementedAccessor);
            }

            this.explicitInterfaceImplementations = explicitInterfaceImplementations;
            this.name  = name;
            this.flags = MakeFlags(
                isAdder ? MethodKind.EventAdd : MethodKind.EventRemove,
                @event.Modifiers,
                returnsVoid: false, // until we learn otherwise (in LazyMethodChecks).
                isExtensionMethod: false,
                isMetadataVirtualIgnoringModifiers: explicitInterfaceImplementations.Any());

            if (@event.ContainingType.IsInterface)
            {
                diagnostics.Add(ErrorCode.ERR_EventPropertyInInterface, this.Location);
            }
            else
            {
                var bodyOpt = syntax.Body;
                if (bodyOpt != null)
                {
                    if (IsExtern && !IsAbstract)
                    {
                        diagnostics.Add(ErrorCode.ERR_ExternHasBody, this.Location, this);
                    }
                    else if (IsAbstract && !IsExtern)
                    {
                        diagnostics.Add(ErrorCode.ERR_AbstractHasBody, this.Location, this);
                    }
                    // Do not report error for IsAbstract && IsExtern. Dev10 reports CS0180 only
                    // in that case ("member cannot be both extern and abstract").
                }
            }

            this.name = GetOverriddenAccessorName(@event, isAdder) ?? this.name;
        }
Ejemplo n.º 15
0
        public bool Equals(Symbol member1, Symbol member2)
        {
            if (ReferenceEquals(member1, member2))
            {
                return(true);
            }

            if ((object)member1 == null || (object)member2 == null || member1.Kind != member2.Kind)
            {
                return(false);
            }

            bool sawInterfaceInName1 = false;
            bool sawInterfaceInName2 = false;

            if (_considerName)
            {
                string name1 = ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(member1.Name);
                string name2 = ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(member2.Name);

                sawInterfaceInName1 = name1 != member1.Name;
                sawInterfaceInName2 = name2 != member2.Name;

                if (name1 != name2)
                {
                    return(false);
                }
            }

            // NB: up to, and including, this check, we have not actually forced the (type) parameters
            // to be expanded - we're only using the counts.
            if ((member1.GetMemberArity() != member2.GetMemberArity()) ||
                (member1.GetParameterCount() != member2.GetParameterCount()))
            {
                return(false);
            }

            var typeMap1 = GetTypeMap(member1);
            var typeMap2 = GetTypeMap(member2);

            if (_considerReturnType && !HaveSameReturnTypes(member1, typeMap1, member2, typeMap2,
                                                            _considerCustomModifiers, _ignoreDynamic, _ignoreTupleNames))
            {
                return(false);
            }

            if (member1.GetParameterCount() > 0 && !HaveSameParameterTypes(member1.GetParameters(), typeMap1, member2.GetParameters(), typeMap2,
                                                                           _considerRefKindDifferences, _considerCustomModifiers, _ignoreDynamic, _ignoreTupleNames))
            {
                return(false);
            }

            if (_considerCallingConvention)
            {
                if (GetCallingConvention(member1) != GetCallingConvention(member2))
                {
                    return(false);
                }
            }
            else
            {
                if (IsVarargMethod(member1) != IsVarargMethod(member2))
                {
                    return(false);
                }
            }

            if (_considerExplicitlyImplementedInterfaces)
            {
                if (sawInterfaceInName1 != sawInterfaceInName2)
                {
                    return(false);
                }

                // The purpose of this check is to determine whether the interface parts of the member names agree,
                // but to do so using robust symbolic checks, rather than syntactic ones.  Therefore, if neither member
                // name contains an interface name, this check is not relevant.
                // Phrased differently, the explicitly implemented interface is not part of the signature unless it's
                // part of the name.
                if (sawInterfaceInName1)
                {
                    Debug.Assert(sawInterfaceInName2);

                    // May avoid realizing interface members.
                    if (member1.IsExplicitInterfaceImplementation() != member2.IsExplicitInterfaceImplementation())
                    {
                        return(false);
                    }

                    // By comparing symbols, rather than syntax, we gain the flexibility of ignoring whitespace
                    // and gracefully accepting multiple names for the same (or equivalent) types (e.g. "I<int>.M"
                    // vs "I<System.Int32>.M"), but we lose the connection with the name.  For example, in metadata,
                    // a method name "I.M" could have nothing to do with "I" but explicitly implement interface "I2".
                    // We will behave as if the method was really named "I2.M".  Furthermore, in metadata, a method
                    // can explicitly implement more than one interface method, in which case it doesn't really
                    // make sense to pretend that all of them are part of the signature.

                    var explicitInterfaceImplementations1 = member1.GetExplicitInterfaceImplementations();
                    var explicitInterfaceImplementations2 = member2.GetExplicitInterfaceImplementations();

                    if (!explicitInterfaceImplementations1.SetEquals(explicitInterfaceImplementations2, EqualityComparer <Symbol> .Default))
                    {
                        return(false);
                    }
                }
            }

            return(!_considerTypeConstraints || HaveSameConstraints(member1, typeMap1, member2, typeMap2));
        }
Ejemplo n.º 16
0
        private static SourcePropertySymbol Create(
            SourceMemberContainerTypeSymbol containingType,
            Binder binder,
            BasePropertyDeclarationSyntax syntax,
            string name,
            Location location,
            BindingDiagnosticBag diagnostics
            )
        {
            GetAccessorDeclarations(
                syntax,
                diagnostics,
                out bool isAutoProperty,
                out bool hasAccessorList,
                out bool accessorsHaveImplementation,
                out bool isInitOnly,
                out var getSyntax,
                out var setSyntax
                );

            var             explicitInterfaceSpecifier        = GetExplicitInterfaceSpecifier(syntax);
            SyntaxTokenList modifiersTokenList                = GetModifierTokensSyntax(syntax);
            bool            isExplicitInterfaceImplementation = explicitInterfaceSpecifier is object;
            var             modifiers = MakeModifiers(
                containingType,
                modifiersTokenList,
                isExplicitInterfaceImplementation,
                isIndexer: syntax.Kind() == SyntaxKind.IndexerDeclaration,
                accessorsHaveImplementation: accessorsHaveImplementation,
                location,
                diagnostics,
                out _
                );

            bool isExpressionBodied = !hasAccessorList && GetArrowExpression(syntax) != null;

            binder = binder.WithUnsafeRegionIfNecessary(modifiersTokenList);
            TypeSymbol?explicitInterfaceType;
            string?    aliasQualifierOpt;
            string     memberName = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(
                binder,
                explicitInterfaceSpecifier,
                name,
                diagnostics,
                out explicitInterfaceType,
                out aliasQualifierOpt
                );

            return(new SourcePropertySymbol(
                       containingType,
                       syntax,
                       hasGetAccessor: getSyntax != null || isExpressionBodied,
                       hasSetAccessor: setSyntax != null,
                       isExplicitInterfaceImplementation,
                       explicitInterfaceType,
                       aliasQualifierOpt,
                       modifiers,
                       isAutoProperty: isAutoProperty,
                       isExpressionBodied: isExpressionBodied,
                       isInitOnly: isInitOnly,
                       memberName,
                       location,
                       diagnostics
                       ));
        }
Ejemplo n.º 17
0
        internal SourceCustomEventSymbol(SourceMemberContainerTypeSymbol containingType, Binder binder, EventDeclarationSyntax syntax, DiagnosticBag diagnostics) :
            base(containingType, syntax, syntax.Modifiers, isFieldLike: false,
                 interfaceSpecifierSyntaxOpt: syntax.ExplicitInterfaceSpecifier,
                 nameTokenSyntax: syntax.Identifier, diagnostics: diagnostics)
        {
            ExplicitInterfaceSpecifierSyntax?interfaceSpecifier = syntax.ExplicitInterfaceSpecifier;
            SyntaxToken nameToken = syntax.Identifier;
            bool        isExplicitInterfaceImplementation = interfaceSpecifier != null;

            string?aliasQualifierOpt;

            _name = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(binder, interfaceSpecifier, nameToken.ValueText, diagnostics, out _explicitInterfaceType, out aliasQualifierOpt);

            _type = BindEventType(binder, syntax.Type, diagnostics);

            var explicitlyImplementedEvent = this.FindExplicitlyImplementedEvent(_explicitInterfaceType, nameToken.ValueText, interfaceSpecifier, diagnostics);

            this.FindExplicitlyImplementedMemberVerification(explicitlyImplementedEvent, diagnostics);

            // 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, 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).

            // 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 event if this is supposed to be an explicit implementation.
            if (!isExplicitInterfaceImplementation)
            {
                // 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);
                    }
                }
            }
            else if ((object)explicitlyImplementedEvent != null)
            {
                CopyEventCustomModifiers(explicitlyImplementedEvent, ref _type, ContainingAssembly);
            }

            AccessorDeclarationSyntax?addSyntax    = null;
            AccessorDeclarationSyntax?removeSyntax = null;

            if (syntax.AccessorList != null)
            {
                foreach (AccessorDeclarationSyntax accessor in syntax.AccessorList.Accessors)
                {
                    bool checkBody = false;

                    switch (accessor.Kind())
                    {
                    case SyntaxKind.AddAccessorDeclaration:
                        if (addSyntax == null)
                        {
                            addSyntax = accessor;
                            checkBody = true;
                        }
                        else
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation());
                        }
                        break;

                    case SyntaxKind.RemoveAccessorDeclaration:
                        if (removeSyntax == null)
                        {
                            removeSyntax = accessor;
                            checkBody    = true;
                        }
                        else
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation());
                        }
                        break;

                    case SyntaxKind.GetAccessorDeclaration:
                    case SyntaxKind.SetAccessorDeclaration:
                        diagnostics.Add(ErrorCode.ERR_AddOrRemoveExpected, accessor.Keyword.GetLocation());
                        break;

                    case SyntaxKind.UnknownAccessorDeclaration:
                        // Don't need to handle UnknownAccessorDeclaration.  An error will have
                        // already been produced for it in the parser.
                        break;

                    default:
                        throw ExceptionUtilities.UnexpectedValue(accessor.Kind());
                    }

                    if (checkBody && !IsAbstract && accessor.Body == null && accessor.ExpressionBody == null && accessor.SemicolonToken.Kind() == SyntaxKind.SemicolonToken)
                    {
                        diagnostics.Add(ErrorCode.ERR_AddRemoveMustHaveBody, accessor.SemicolonToken.GetLocation());
                    }
                }

                if (IsAbstract)
                {
                    if (!syntax.AccessorList.OpenBraceToken.IsMissing)
                    {
                        diagnostics.Add(ErrorCode.ERR_AbstractEventHasAccessors, syntax.AccessorList.OpenBraceToken.GetLocation(), this);
                    }
                }
                else if ((addSyntax == null || removeSyntax == null) && (!syntax.AccessorList.OpenBraceToken.IsMissing || !isExplicitInterfaceImplementation))
                {
                    diagnostics.Add(ErrorCode.ERR_EventNeedsBothAccessors, this.Locations[0], this);
                }
            }
            else if (isExplicitInterfaceImplementation && !IsAbstract)
            {
                diagnostics.Add(ErrorCode.ERR_ExplicitEventFieldImpl, this.Locations[0]);
            }

            if (isExplicitInterfaceImplementation && IsAbstract && syntax.AccessorList == null)
            {
                Debug.Assert(containingType.IsInterface);

                Binder.CheckFeatureAvailability(syntax, MessageID.IDS_DefaultInterfaceImplementation, diagnostics, this.Locations[0]);

                if (!ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation)
                {
                    diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, this.Locations[0]);
                }

                _addMethod    = new SynthesizedEventAccessorSymbol(this, isAdder: true, explicitlyImplementedEvent, aliasQualifierOpt);
                _removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false, explicitlyImplementedEvent, aliasQualifierOpt);
            }
            else
            {
                _addMethod    = CreateAccessorSymbol(addSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics);
                _removeMethod = CreateAccessorSymbol(removeSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics);
            }

            _explicitInterfaceImplementations =
                (object?)explicitlyImplementedEvent == null ?
                ImmutableArray <EventSymbol> .Empty :
                ImmutableArray.Create <EventSymbol>(explicitlyImplementedEvent);
        }
Ejemplo n.º 18
0
        internal SourceCustomEventSymbol(SourceMemberContainerTypeSymbol containingType, Binder binder, EventDeclarationSyntax syntax, DiagnosticBag diagnostics) :
            base(containingType, syntax, syntax.Modifiers, syntax.ExplicitInterfaceSpecifier, syntax.Identifier, diagnostics)
        {
            ExplicitInterfaceSpecifierSyntax interfaceSpecifier = syntax.ExplicitInterfaceSpecifier;
            SyntaxToken nameToken = syntax.Identifier;
            bool        isExplicitInterfaceImplementation = interfaceSpecifier != null;

            string aliasQualifierOpt;

            _name = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(binder, interfaceSpecifier, nameToken.ValueText, diagnostics, out _explicitInterfaceType, out aliasQualifierOpt);

            _type = BindEventType(binder, syntax.Type, diagnostics);

            var explicitlyImplementedEvent = this.FindExplicitlyImplementedEvent(_explicitInterfaceType, nameToken.ValueText, interfaceSpecifier, diagnostics);

            this.FindExplicitlyImplementedMemberVerification(explicitlyImplementedEvent, diagnostics);

            // 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, 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).

            // 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 event if this is supposed to be an explicit implementation.
            if (!isExplicitInterfaceImplementation)
            {
                // 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);
                    }
                }
            }
            else if ((object)explicitlyImplementedEvent != null)
            {
                CopyEventCustomModifiers(explicitlyImplementedEvent, ref _type, ContainingAssembly);
            }

            AccessorDeclarationSyntax addSyntax    = null;
            AccessorDeclarationSyntax removeSyntax = null;

            foreach (AccessorDeclarationSyntax accessor in syntax.AccessorList.Accessors)
            {
                switch (accessor.Kind())
                {
                case SyntaxKind.AddAccessorDeclaration:
                    if (addSyntax == null)
                    {
                        addSyntax = accessor;
                    }
                    else
                    {
                        diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation());
                    }
                    break;

                case SyntaxKind.RemoveAccessorDeclaration:
                    if (removeSyntax == null)
                    {
                        removeSyntax = accessor;
                    }
                    else
                    {
                        diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, accessor.Keyword.GetLocation());
                    }
                    break;

                case SyntaxKind.GetAccessorDeclaration:
                case SyntaxKind.SetAccessorDeclaration:
                    diagnostics.Add(ErrorCode.ERR_AddOrRemoveExpected, accessor.Keyword.GetLocation());
                    break;

                case SyntaxKind.UnknownAccessorDeclaration:
                    // Don't need to handle UnknownAccessorDeclaration.  An error will have
                    // already been produced for it in the parser.
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(accessor.Kind());
                }
            }

            _addMethod    = CreateAccessorSymbol(addSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics);
            _removeMethod = CreateAccessorSymbol(removeSyntax, explicitlyImplementedEvent, aliasQualifierOpt, diagnostics);

            if (containingType.IsInterfaceType())
            {
                if (addSyntax == null && removeSyntax == null) //NOTE: AND - different error code produced if one is present
                {
                    // CONSIDER: we're matching dev10, but it would probably be more helpful to give
                    // an error like ERR_EventPropertyInInterface.
                    diagnostics.Add(ErrorCode.ERR_EventNeedsBothAccessors, this.Locations[0], this);
                }
            }
            else
            {
                if (addSyntax == null || removeSyntax == null)
                {
                    diagnostics.Add(ErrorCode.ERR_EventNeedsBothAccessors, this.Locations[0], this);
                }
            }

            _explicitInterfaceImplementations =
                (object)explicitlyImplementedEvent == null ?
                ImmutableArray <EventSymbol> .Empty :
                ImmutableArray.Create <EventSymbol>(explicitlyImplementedEvent);
        }
        public bool Equals(Symbol member1, Symbol member2)
        {
            if (ReferenceEquals(member1, member2))
            {
                return(true);
            }

            if ((object)member1 == null || (object)member2 == null || member1.Kind != member2.Kind)
            {
                return(false);
            }

            bool sawInterfaceInName1 = false;
            bool sawInterfaceInName2 = false;

            if (_considerName)
            {
                string name1 = ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(member1.Name);
                string name2 = ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(member2.Name);

                sawInterfaceInName1 = name1 != member1.Name;
                sawInterfaceInName2 = name2 != member2.Name;

                if (name1 != name2)
                {
                    return(false);
                }
            }

            // NB: up to, and including, this check, we have not actually forced the (type) parameters
            // to be expanded - we're only using the counts.
            int arity = member1.GetMemberArity();

            if ((arity != member2.GetMemberArity()) ||
                (member1.GetParameterCount() != member2.GetParameterCount()))
            {
                return(false);
            }

            TypeMap typeMap1;
            TypeMap typeMap2;

            if (arity > 0 && _useSpecialHandlingForNullableTypes)
            {
                // We need this special handling in order to avoid forcing resolution of nullable types
                // in signature of an overriding member while we are looking for a matching overridden member.
                // Doing the resolution in the original signature can send us into an infinite cycle because
                // constraints must be inherited from the member we are looking for.
                // It is important to ensure that the fact whether an indexed type parameter we are about to use
                // is a reference type is inherited from the corresponding type parameter of the possibly overridden
                // member (which is member2 when _useSpecialHandlingForNullableTypes is true). This will ensure
                // proper resolution for nullable types in substituted signature of member1, ensuring proper
                // comparison of types across both members.
                ArrayBuilder <TypeParameterSymbol> builder = ArrayBuilder <TypeParameterSymbol> .GetInstance(arity);

                var typeParameters2 = member2.GetMemberTypeParameters();

                for (int i = arity - 1; i >= 0; i--)
                {
                    builder.Add(IndexedTypeParameterSymbolForOverriding.GetTypeParameter(i, typeParameters2[i].IsValueType));
                }

                var indexed = builder.ToImmutableAndFree();

                typeMap1 = new TypeMap(member1.GetMemberTypeParameters(), indexed, true);
                typeMap2 = new TypeMap(typeParameters2, indexed, true);
            }
            else
            {
                typeMap1 = GetTypeMap(member1);
                typeMap2 = GetTypeMap(member2);
            }

            if (_considerReturnType && !HaveSameReturnTypes(member1, typeMap1, member2, typeMap2, _typeComparison))
            {
                return(false);
            }

            if (member1.GetParameterCount() > 0 && !HaveSameParameterTypes(member1.GetParameters(), typeMap1, member2.GetParameters(), typeMap2,
                                                                           _considerRefKindDifferences, _typeComparison))
            {
                return(false);
            }

            if (_considerCallingConvention)
            {
                if (GetCallingConvention(member1) != GetCallingConvention(member2))
                {
                    return(false);
                }
            }
            else
            {
                if (IsVarargMethod(member1) != IsVarargMethod(member2))
                {
                    return(false);
                }
            }

            if (_considerExplicitlyImplementedInterfaces)
            {
                if (sawInterfaceInName1 != sawInterfaceInName2)
                {
                    return(false);
                }

                // The purpose of this check is to determine whether the interface parts of the member names agree,
                // but to do so using robust symbolic checks, rather than syntactic ones.  Therefore, if neither member
                // name contains an interface name, this check is not relevant.
                // Phrased differently, the explicitly implemented interface is not part of the signature unless it's
                // part of the name.
                if (sawInterfaceInName1)
                {
                    Debug.Assert(sawInterfaceInName2);

                    // May avoid realizing interface members.
                    if (member1.IsExplicitInterfaceImplementation() != member2.IsExplicitInterfaceImplementation())
                    {
                        return(false);
                    }

                    // By comparing symbols, rather than syntax, we gain the flexibility of ignoring whitespace
                    // and gracefully accepting multiple names for the same (or equivalent) types (e.g. "I<int>.M"
                    // vs "I<System.Int32>.M"), but we lose the connection with the name.  For example, in metadata,
                    // a method name "I.M" could have nothing to do with "I" but explicitly implement interface "I2".
                    // We will behave as if the method was really named "I2.M".  Furthermore, in metadata, a method
                    // can explicitly implement more than one interface method, in which case it doesn't really
                    // make sense to pretend that all of them are part of the signature.

                    var explicitInterfaceImplementations1 = member1.GetExplicitInterfaceImplementations();
                    var explicitInterfaceImplementations2 = member2.GetExplicitInterfaceImplementations();

                    if (!explicitInterfaceImplementations1.SetEquals(explicitInterfaceImplementations2, EqualityComparer <Symbol> .Default))
                    {
                        return(false);
                    }
                }
            }

            return(!_considerTypeConstraints || HaveSameConstraints(member1, typeMap1, member2, typeMap2));
        }