public static SourceUserDefinedConversionSymbol CreateUserDefinedConversionSymbol( SourceMemberContainerTypeSymbol containingType, Binder bodyBinder, ConversionOperatorDeclarationSyntax syntax, bool isNullableAnalysisEnabled, BindingDiagnosticBag diagnostics) { // Dev11 includes the explicit/implicit keyword, but we don't have a good way to include // Narrowing/Widening in VB and we want the languages to be consistent. var location = syntax.Type.Location; string name = OperatorFacts.OperatorNameFromDeclaration(syntax); if (name == WellKnownMemberNames.CheckedExplicitConversionName) { MessageID.IDS_FeatureCheckedUserDefinedOperators.CheckFeatureAvailability(diagnostics, syntax, syntax.CheckedKeyword.GetLocation()); } else if (syntax.CheckedKeyword.IsKind(SyntaxKind.CheckedKeyword)) { diagnostics.Add(ErrorCode.ERR_ImplicitConversionOperatorCantBeChecked, syntax.CheckedKeyword.GetLocation()); } var interfaceSpecifier = syntax.ExplicitInterfaceSpecifier; TypeSymbol explicitInterfaceType; name = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(bodyBinder, interfaceSpecifier, name, diagnostics, out explicitInterfaceType, aliasQualifierOpt: out _); var methodKind = interfaceSpecifier == null ? MethodKind.Conversion : MethodKind.ExplicitInterfaceImplementation; return(new SourceUserDefinedConversionSymbol( methodKind, containingType, explicitInterfaceType, name, location, syntax, isNullableAnalysisEnabled, diagnostics)); }
public static SourceUserDefinedConversionSymbol CreateUserDefinedConversionSymbol( SourceMemberContainerTypeSymbol containingType, Binder bodyBinder, ConversionOperatorDeclarationSyntax syntax, bool isNullableAnalysisEnabled, BindingDiagnosticBag diagnostics) { // Dev11 includes the explicit/implicit keyword, but we don't have a good way to include // Narrowing/Widening in VB and we want the languages to be consistent. var location = syntax.Type.Location; 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.Conversion : MethodKind.ExplicitInterfaceImplementation; return(new SourceUserDefinedConversionSymbol( methodKind, containingType, explicitInterfaceType, name, location, syntax, isNullableAnalysisEnabled, diagnostics)); }
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))); } 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)); }
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)); }
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)); }
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)); }
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); }
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); }