internal virtual void PostDecodeWellKnownAttributes( ImmutableArray <CSharpAttributeData> boundAttributes, ImmutableArray <AttributeSyntax> allAttributeSyntaxNodes, BindingDiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData ) { }
internal override void PostDecodeWellKnownAttributes( ImmutableArray <CSharpAttributeData> boundAttributes, ImmutableArray <AttributeSyntax> allAttributeSyntaxNodes, BindingDiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData ) { base.PostDecodeWellKnownAttributes( boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData ); if (!allAttributeSyntaxNodes.IsEmpty && _property.IsAutoPropertyWithGetAccessor) { CheckForFieldTargetedAttribute(diagnostics); } }
internal override void PostDecodeWellKnownAttributes(ImmutableArray<CSharpAttributeData> boundAttributes, ImmutableArray<AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(_lazyCustomAttributesBag != null); Debug.Assert(_lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); if (this.IsAutoProperty && !this.IsStatic && this.ContainingType.Layout.Kind == LayoutKind.Explicit) { // error CS0842: '<property>': Automatically implemented properties cannot be used inside a type marked with StructLayout(LayoutKind.Explicit) diagnostics.Add(ErrorCode.ERR_ExplicitLayoutAndAutoImplementedProperty, this.Location, this); } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
/// <summary> /// Called to report attribute related diagnostics after all attributes have been bound and decoded. /// Called even if there are no attributes. /// </summary> /// <remarks> /// This method is called by the binder from <see cref="LoadAndValidateAttributes"/> after it has finished binding attributes on the symbol, /// has executed <see cref="DecodeWellKnownAttribute"/> for attributes applied on the symbol and has stored the decoded data in the /// lazyCustomAttributesBag on the symbol. Bound attributes haven't been stored on the bag yet. /// /// Post-validation for attributes that is dependant on other attributes can be done here. /// /// This method should not have any side effects on the symbol, i.e. it SHOULD NOT change the symbol state. /// </remarks> /// <param name="boundAttributes">Bound attributes.</param> /// <param name="allAttributeSyntaxNodes">Syntax nodes of attributes in order they are specified in source, or null if there are no attributes.</param> /// <param name="diagnostics">Diagnostic bag.</param> /// <param name="symbolPart">Specific part of the symbol to which the attributes apply, or <see cref="AttributeLocation.None"/> if the attributes apply to the symbol itself.</param> /// <param name="decodedData">Decoded well-known attribute data, could be null.</param> internal virtual void PostDecodeWellKnownAttributes(ImmutableArray<CSharpAttributeData> boundAttributes, ImmutableArray<AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { }
internal override void PostDecodeWellKnownAttributes(ImmutableArray <CSharpAttributeData> boundAttributes, ImmutableArray <AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(this.lazyCustomAttributesBag != null); Debug.Assert(this.lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); var data = (CommonFieldWellKnownAttributeData)decodedData; int?fieldOffset = data != null ? data.Offset : null; if (fieldOffset.HasValue) { if (this.ContainingType.Layout.Kind != LayoutKind.Explicit) { Debug.Assert(boundAttributes.Any()); // error CS0636: The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit) int i = boundAttributes.IndexOfAttribute(this, AttributeDescription.FieldOffsetAttribute); diagnostics.Add(ErrorCode.ERR_StructOffsetOnBadStruct, allAttributeSyntaxNodes[i].Name.Location); } } else if (!this.IsStatic && !this.IsConst) { if (this.ContainingType.Layout.Kind == LayoutKind.Explicit) { // error CS0625: '<field>': instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute diagnostics.Add(ErrorCode.ERR_MissingStructOffset, this.ErrorLocation, this); } } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
internal override void PostDecodeWellKnownAttributes(ImmutableArray <CSharpAttributeData> boundAttributes, ImmutableArray <AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(this.lazyCustomAttributesBag != null); Debug.Assert(this.lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); var data = (CommonParameterWellKnownAttributeData)decodedData; if (data != null) { if (this.RefKind == RefKind.Ref && data.HasOutAttribute && !data.HasInAttribute) { // error CS0662: '...' cannot specify only Out attribute on a ref parameter. Use both In and Out attributes, or neither. diagnostics.Add(ErrorCode.ERR_OutAttrOnRefParam, this.Locations[0]); } } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
internal override void PostDecodeWellKnownAttributes(ImmutableArray <CSharpAttributeData> boundAttributes, ImmutableArray <AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(this.lazyCustomAttributesBag != null); Debug.Assert(this.lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); var data = (TypeWellKnownAttributeData)decodedData; if (this.IsComImport) { Debug.Assert(boundAttributes.Any()); // Symbol with ComImportAttribute must have a GuidAttribute if (data == null || data.GuidString == null) { int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.ComImportAttribute); diagnostics.Add(ErrorCode.ERR_ComImportWithoutUuidAttribute, allAttributeSyntaxNodes[index].Name.Location, this.Name); } if (this.TypeKind == TypeKind.Class) { var baseType = this.BaseTypeNoUseSiteDiagnostics; if ((object)baseType != null && baseType.SpecialType != SpecialType.System_Object) { // CS0424: '{0}': a class with the ComImport attribute cannot specify a base class diagnostics.Add(ErrorCode.ERR_ComImportWithBase, this.Locations[0], this.Name); } var initializers = this.StaticInitializers; if (!initializers.IsDefaultOrEmpty) { foreach (var initializerGroup in initializers) { foreach (var singleInitializer in initializerGroup) { if (!singleInitializer.FieldOpt.IsMetadataConstant) { // CS8028: '{0}': a class with the ComImport attribute cannot specify field initializers. diagnostics.Add(ErrorCode.ERR_ComImportWithInitializers, singleInitializer.Syntax.GetLocation(), this.Name); } } } } initializers = this.InstanceInitializers; if (!initializers.IsDefaultOrEmpty) { foreach (var initializerGroup in initializers) { foreach (var singleInitializer in initializerGroup) { // CS8028: '{0}': a class with the ComImport attribute cannot specify field initializers. diagnostics.Add(ErrorCode.ERR_ComImportWithInitializers, singleInitializer.Syntax.GetLocation(), this.Name); } } } } } else if ((object)this.ComImportCoClass != null) { Debug.Assert(boundAttributes.Any()); // Symbol with CoClassAttribute must have a ComImportAttribute int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.CoClassAttribute); diagnostics.Add(ErrorCode.WRN_CoClassWithoutComImport, allAttributeSyntaxNodes[index].Location, this.Name); } // Report ERR_DefaultMemberOnIndexedType if type has a default member attribute and has indexers. if (data != null && data.HasDefaultMemberAttribute && this.Indexers.Any()) { Debug.Assert(boundAttributes.Any()); int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.DefaultMemberAttribute); diagnostics.Add(ErrorCode.ERR_DefaultMemberOnIndexedType, allAttributeSyntaxNodes[index].Name.Location); } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
internal override void PostDecodeWellKnownAttributes(ImmutableArray<CSharpAttributeData> boundAttributes, ImmutableArray<AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(_lazyCustomAttributesBag != null); Debug.Assert(_lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); var data = (TypeWellKnownAttributeData)decodedData; if (this.IsComImport) { Debug.Assert(boundAttributes.Any()); // Symbol with ComImportAttribute must have a GuidAttribute if (data == null || data.GuidString == null) { int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.ComImportAttribute); diagnostics.Add(ErrorCode.ERR_ComImportWithoutUuidAttribute, allAttributeSyntaxNodes[index].Name.Location, this.Name); } if (this.TypeKind == TypeKind.Class) { var baseType = this.BaseTypeNoUseSiteDiagnostics; if ((object)baseType != null && baseType.SpecialType != SpecialType.System_Object) { // CS0424: '{0}': a class with the ComImport attribute cannot specify a base class diagnostics.Add(ErrorCode.ERR_ComImportWithBase, this.Locations[0], this.Name); } var initializers = this.StaticInitializers; if (!initializers.IsDefaultOrEmpty) { foreach (var initializerGroup in initializers) { foreach (var singleInitializer in initializerGroup) { if (!singleInitializer.FieldOpt.IsMetadataConstant) { // CS8028: '{0}': a class with the ComImport attribute cannot specify field initializers. diagnostics.Add(ErrorCode.ERR_ComImportWithInitializers, singleInitializer.Syntax.GetLocation(), this.Name); } } } } initializers = this.InstanceInitializers; if (!initializers.IsDefaultOrEmpty) { foreach (var initializerGroup in initializers) { foreach (var singleInitializer in initializerGroup) { // CS8028: '{0}': a class with the ComImport attribute cannot specify field initializers. diagnostics.Add(ErrorCode.ERR_ComImportWithInitializers, singleInitializer.Syntax.GetLocation(), this.Name); } } } } } else if ((object)this.ComImportCoClass != null) { Debug.Assert(boundAttributes.Any()); // Symbol with CoClassAttribute must have a ComImportAttribute int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.CoClassAttribute); diagnostics.Add(ErrorCode.WRN_CoClassWithoutComImport, allAttributeSyntaxNodes[index].Location, this.Name); } // Report ERR_DefaultMemberOnIndexedType if type has a default member attribute and has indexers. if (data != null && data.HasDefaultMemberAttribute && this.Indexers.Any()) { Debug.Assert(boundAttributes.Any()); int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.DefaultMemberAttribute); diagnostics.Add(ErrorCode.ERR_DefaultMemberOnIndexedType, allAttributeSyntaxNodes[index].Name.Location); } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
internal override void PostDecodeWellKnownAttributes(ImmutableArray <CSharpAttributeData> boundAttributes, ImmutableArray <AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(_lazyCustomAttributesBag != null); Debug.Assert(_lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); var data = (CommonParameterWellKnownAttributeData)decodedData; if (data != null) { switch (RefKind) { case RefKind.Ref: if (data.HasOutAttribute && !data.HasInAttribute) { // error CS0662: Cannot specify the Out attribute on a ref parameter without also specifying the In attribute. diagnostics.Add(ErrorCode.ERR_OutAttrOnRefParam, this.Locations[0]); } break; case RefKind.Out: if (data.HasInAttribute) { // error CS0036: An out parameter cannot have the In attribute. diagnostics.Add(ErrorCode.ERR_InAttrOnOutParam, this.Locations[0]); } break; case RefKind.In: if (data.HasOutAttribute) { // error CS8355: An in parameter cannot have the Out attribute. diagnostics.Add(ErrorCode.ERR_OutAttrOnInParam, this.Locations[0]); } break; } } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
internal override void PostDecodeWellKnownAttributes(ImmutableArray <CSharpAttributeData> boundAttributes, ImmutableArray <AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(_lazyCustomAttributesBag != null); Debug.Assert(_lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); var data = (TypeWellKnownAttributeData)decodedData; // Report ERR_DefaultMemberOnIndexedType if type has a default member attribute and has indexers. if (data != null && data.HasDefaultMemberAttribute && this.Indexers.Any()) { Debug.Assert(boundAttributes.Any()); int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.DefaultMemberAttribute); diagnostics.Add(ErrorCode.ERR_DefaultMemberOnIndexedType, allAttributeSyntaxNodes[index].Name.Location); } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
internal override void PostDecodeWellKnownAttributes(ImmutableArray<CSharpAttributeData> boundAttributes, ImmutableArray<AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(_lazyCustomAttributesBag != null); Debug.Assert(_lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); var data = (CommonFieldWellKnownAttributeData)decodedData; int? fieldOffset = data != null ? data.Offset : null; if (fieldOffset.HasValue) { if (this.ContainingType.Layout.Kind != LayoutKind.Explicit) { Debug.Assert(boundAttributes.Any()); // error CS0636: The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit) int i = boundAttributes.IndexOfAttribute(this, AttributeDescription.FieldOffsetAttribute); diagnostics.Add(ErrorCode.ERR_StructOffsetOnBadStruct, allAttributeSyntaxNodes[i].Name.Location); } } else if (!this.IsStatic && !this.IsConst) { if (this.ContainingType.Layout.Kind == LayoutKind.Explicit) { // error CS0625: '<field>': instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute diagnostics.Add(ErrorCode.ERR_MissingStructOffset, this.ErrorLocation, this); } } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
internal override void PostDecodeWellKnownAttributes(ImmutableArray<CSharpAttributeData> boundAttributes, ImmutableArray<AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(symbolPart == AttributeLocation.None || symbolPart == AttributeLocation.Return); if (symbolPart != AttributeLocation.Return) { Debug.Assert(this.lazyCustomAttributesBag != null); Debug.Assert(this.lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); if (this.containingType.IsComImport && this.containingType.TypeKind == TypeKind.Class) { switch (this.MethodKind) { case MethodKind.Constructor: case MethodKind.StaticConstructor: if (!this.IsImplicitlyDeclared) { // CS0669: A class with the ComImport attribute cannot have a user-defined constructor diagnostics.Add(ErrorCode.ERR_ComImportWithUserCtor, this.Locations[0]); } break; default: if (!this.IsAbstract && !this.IsExtern) { // CS0423: Since '{1}' has the ComImport attribute, '{0}' must be extern or abstract diagnostics.Add(ErrorCode.ERR_ComImportWithImpl, this.Locations[0], this, this.containingType); } break; } } } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
internal override void PostDecodeWellKnownAttributes(ImmutableArray<CSharpAttributeData> boundAttributes, ImmutableArray<AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(_lazyCustomAttributesBag != null); Debug.Assert(_lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); var data = (CommonParameterWellKnownAttributeData)decodedData; if (data != null) { if (this.RefKind == RefKind.Ref && data.HasOutAttribute && !data.HasInAttribute) { // error CS0662: '...' cannot specify only Out attribute on a ref parameter. Use both In and Out attributes, or neither. diagnostics.Add(ErrorCode.ERR_OutAttrOnRefParam, this.Locations[0]); } } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }