Пример #1
0
            private ImmutableArray <TAttributeData> GetAttributes(TModuleCompilationState compilationState, TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
            {
                ArrayBuilder <TAttributeData> builder = ArrayBuilder <TAttributeData> .GetInstance();

                // Copy some of the attributes.

                // Note, when porting attributes, we are not using constructors from original symbol.
                // The constructors might be missing (for example, in metadata case) and doing lookup
                // will ensure that we report appropriate errors.

                foreach (TAttributeData attrData in GetCustomAttributesToEmit(compilationState))
                {
                    if (IsTargetAttribute(attrData, AttributeDescription.ParamArrayAttribute))
                    {
                        if (attrData.CommonConstructorArguments.Length == 0)
                        {
                            builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_ParamArrayAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));
                        }
                    }
                    else if (IsTargetAttribute(attrData, AttributeDescription.DateTimeConstantAttribute))
                    {
                        if (attrData.CommonConstructorArguments.Length == 1)
                        {
                            builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_CompilerServices_DateTimeConstantAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));
                        }
                    }
                    else
                    {
                        int signatureIndex = TypeManager.GetTargetAttributeSignatureIndex(UnderlyingParameter, attrData, AttributeDescription.DecimalConstantAttribute);
                        if (signatureIndex != -1)
                        {
                            Debug.Assert(signatureIndex == 0 || signatureIndex == 1);

                            if (attrData.CommonConstructorArguments.Length == 5)
                            {
                                builder.AddOptional(TypeManager.CreateSynthesizedAttribute(
                                                        signatureIndex == 0 ? WellKnownMember.System_Runtime_CompilerServices_DecimalConstantAttribute__ctor :
                                                        WellKnownMember.System_Runtime_CompilerServices_DecimalConstantAttribute__ctorByteByteInt32Int32Int32,
                                                        attrData, syntaxNodeOpt, diagnostics));
                            }
                        }
                        else if (IsTargetAttribute(attrData, AttributeDescription.DefaultParameterValueAttribute))
                        {
                            if (attrData.CommonConstructorArguments.Length == 1)
                            {
                                builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_DefaultParameterValueAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));
                            }
                        }
                    }
                }

                return(builder.ToImmutableAndFree());
            }
Пример #2
0
 protected abstract IEnumerable <TAttributeData> GetCustomAttributesToEmit(TModuleCompilationState compilationState);
Пример #3
0
            private ImmutableArray <TAttributeData> GetAttributes(TModuleCompilationState compilationState, TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
            {
                var builder = ArrayBuilder <TAttributeData> .GetInstance();

                // Put the CompilerGenerated attribute on the NoPIA types we define so that
                // static analysis tools (e.g. fxcop) know that they can be skipped
                builder.AddOptional(TypeManager.CreateCompilerGeneratedAttribute());

                // Copy some of the attributes.

                bool hasGuid = false;
                bool hasComEventInterfaceAttribute = false;

                // Note, when porting attributes, we are not using constructors from original symbol.
                // The constructors might be missing (for example, in metadata case) and doing lookup
                // will ensure that we report appropriate errors.

                foreach (var attrData in GetCustomAttributesToEmit(compilationState))
                {
                    if (IsTargetAttribute(attrData, AttributeDescription.GuidAttribute))
                    {
                        string guidString;
                        if (attrData.TryGetGuidAttributeValue(out guidString))
                        {
                            // If this type has a GuidAttribute, we should emit it.
                            hasGuid = true;
                            builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_GuidAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));
                        }
                    }
                    else if (IsTargetAttribute(attrData, AttributeDescription.ComEventInterfaceAttribute))
                    {
                        if (attrData.CommonConstructorArguments.Length == 2)
                        {
                            hasComEventInterfaceAttribute = true;
                            builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_ComEventInterfaceAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));
                        }
                    }
                    else
                    {
                        int signatureIndex = TypeManager.GetTargetAttributeSignatureIndex(UnderlyingNamedType, attrData, AttributeDescription.InterfaceTypeAttribute);
                        if (signatureIndex != -1)
                        {
                            Debug.Assert(signatureIndex == 0 || signatureIndex == 1);
                            if (attrData.CommonConstructorArguments.Length == 1)
                            {
                                builder.AddOptional(TypeManager.CreateSynthesizedAttribute(signatureIndex == 0 ? WellKnownMember.System_Runtime_InteropServices_InterfaceTypeAttribute__ctorInt16 :
                                                                                           WellKnownMember.System_Runtime_InteropServices_InterfaceTypeAttribute__ctorComInterfaceType,
                                                                                           attrData, syntaxNodeOpt, diagnostics));
                            }
                        }
                        else if (IsTargetAttribute(attrData, AttributeDescription.BestFitMappingAttribute))
                        {
                            if (attrData.CommonConstructorArguments.Length == 1)
                            {
                                builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_BestFitMappingAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));
                            }
                        }
                        else if (IsTargetAttribute(attrData, AttributeDescription.CoClassAttribute))
                        {
                            if (attrData.CommonConstructorArguments.Length == 1)
                            {
                                builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_CoClassAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));
                            }
                        }
                        else if (IsTargetAttribute(attrData, AttributeDescription.FlagsAttribute))
                        {
                            if (attrData.CommonConstructorArguments.Length == 0 && UnderlyingNamedType.IsEnum)
                            {
                                builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_FlagsAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));
                            }
                        }
                        else if (IsTargetAttribute(attrData, AttributeDescription.DefaultMemberAttribute))
                        {
                            if (attrData.CommonConstructorArguments.Length == 1)
                            {
                                builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Reflection_DefaultMemberAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));

                                // Embed members matching default member name.
                                string defaultMember = attrData.CommonConstructorArguments[0].Value as string;
                                if (defaultMember != null)
                                {
                                    EmbedDefaultMembers(defaultMember, syntaxNodeOpt, diagnostics);
                                }
                            }
                        }
                        else if (IsTargetAttribute(attrData, AttributeDescription.UnmanagedFunctionPointerAttribute))
                        {
                            if (attrData.CommonConstructorArguments.Length == 1)
                            {
                                builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_UnmanagedFunctionPointerAttribute__ctor, attrData, syntaxNodeOpt, diagnostics));
                            }
                        }
                    }
                }

                // We must emit a TypeIdentifier attribute which connects this local type with the canonical type.
                // Interfaces usually have a guid attribute, in which case the TypeIdentifier attribute we emit will
                // not need any additional parameters. For interfaces which lack a guid and all other types, we must
                // emit a TypeIdentifier that has parameters identifying the scope and name of the original type. We
                // will use the Assembly GUID as the scope identifier.

                if (IsInterface && !hasComEventInterfaceAttribute)
                {
                    if (!IsComImport)
                    {
                        // If we have an interface not marked ComImport, but the assembly is linked, then
                        // we need to give an error. We allow event interfaces to not have ComImport marked on them.
                        // ERRID_NoPIAAttributeMissing2/ERR_InteropTypeMissingAttribute
                        ReportMissingAttribute(AttributeDescription.ComImportAttribute, syntaxNodeOpt, diagnostics);
                    }
                    else if (!hasGuid)
                    {
                        // Interfaces used with No-PIA ought to have a guid attribute, or the CLR cannot do type unification.
                        // This interface lacks a guid, so unification probably won't work. We allow event interfaces to not have a Guid.
                        // ERRID_NoPIAAttributeMissing2/ERR_InteropTypeMissingAttribute
                        ReportMissingAttribute(AttributeDescription.GuidAttribute, syntaxNodeOpt, diagnostics);
                    }
                }

                // Note, this logic should match the one in RetargetingSymbolTranslator.RetargetNoPiaLocalType
                // when we try to predict what attributes we will emit on embedded type, which corresponds the
                // type we are retargeting.

                builder.AddOptional(CreateTypeIdentifierAttribute(hasGuid && IsInterface, syntaxNodeOpt, diagnostics));

                return(builder.ToImmutableAndFree());
            }