public IEnumerable <IAttribute> GetAttributes() { var b = new AttributeListBuilder(module); var metadata = module.metadata; var typeDefinition = metadata.GetTypeDefinition(handle); // SerializableAttribute if ((typeDefinition.Attributes & TypeAttributes.Serializable) != 0) { b.Add(KnownAttribute.Serializable); } // ComImportAttribute if ((typeDefinition.Attributes & TypeAttributes.Import) != 0) { b.Add(KnownAttribute.ComImport); } #region StructLayoutAttribute LayoutKind layoutKind = LayoutKind.Auto; switch (typeDefinition.Attributes & TypeAttributes.LayoutMask) { case TypeAttributes.SequentialLayout: layoutKind = LayoutKind.Sequential; break; case TypeAttributes.ExplicitLayout: layoutKind = LayoutKind.Explicit; break; } CharSet charSet = CharSet.None; switch (typeDefinition.Attributes & TypeAttributes.StringFormatMask) { case TypeAttributes.AnsiClass: charSet = CharSet.Ansi; break; case TypeAttributes.AutoClass: charSet = CharSet.Auto; break; case TypeAttributes.UnicodeClass: charSet = CharSet.Unicode; break; } var layout = typeDefinition.GetLayout(); LayoutKind defaultLayoutKind = Kind == TypeKind.Struct ? LayoutKind.Sequential : LayoutKind.Auto; if (layoutKind != defaultLayoutKind || charSet != CharSet.Ansi || layout.PackingSize > 0 || layout.Size > 0) { var structLayout = new AttributeBuilder(module, KnownAttribute.StructLayout); structLayout.AddFixedArg( new TopLevelTypeName("System.Runtime.InteropServices", "LayoutKind"), (int)layoutKind); if (charSet != CharSet.Ansi) { var charSetType = Compilation.FindType(new TopLevelTypeName("System.Runtime.InteropServices", "CharSet")); structLayout.AddNamedArg("CharSet", charSetType, (int)charSet); } if (layout.PackingSize > 0) { structLayout.AddNamedArg("Pack", KnownTypeCode.Int32, (int)layout.PackingSize); } if (layout.Size > 0) { structLayout.AddNamedArg("Size", KnownTypeCode.Int32, (int)layout.Size); } b.Add(structLayout.Build()); } #endregion b.Add(typeDefinition.GetCustomAttributes(), SymbolKind.TypeDefinition); b.AddSecurityAttributes(typeDefinition.GetDeclarativeSecurityAttributes()); return(b.Build()); }
public IEnumerable <IAttribute> GetAttributes() { var b = new AttributeListBuilder(module); var metadata = module.metadata; var def = metadata.GetMethodDefinition(handle); MethodImplAttributes implAttributes = def.ImplAttributes & ~MethodImplAttributes.CodeTypeMask; #region DllImportAttribute var info = def.GetImport(); if ((attributes & MethodAttributes.PinvokeImpl) == MethodAttributes.PinvokeImpl && !info.Module.IsNil) { var dllImport = new AttributeBuilder(module, KnownAttribute.DllImport); dllImport.AddFixedArg(KnownTypeCode.String, metadata.GetString(metadata.GetModuleReference(info.Module).Name)); var importAttrs = info.Attributes; if ((importAttrs & MethodImportAttributes.BestFitMappingDisable) == MethodImportAttributes.BestFitMappingDisable) { dllImport.AddNamedArg("BestFitMapping", KnownTypeCode.Boolean, false); } if ((importAttrs & MethodImportAttributes.BestFitMappingEnable) == MethodImportAttributes.BestFitMappingEnable) { dllImport.AddNamedArg("BestFitMapping", KnownTypeCode.Boolean, true); } CallingConvention callingConvention; switch (info.Attributes & MethodImportAttributes.CallingConventionMask) { case 0: Debug.WriteLine($"P/Invoke calling convention not set on: {this}"); callingConvention = 0; break; case MethodImportAttributes.CallingConventionCDecl: callingConvention = CallingConvention.Cdecl; break; case MethodImportAttributes.CallingConventionFastCall: callingConvention = CallingConvention.FastCall; break; case MethodImportAttributes.CallingConventionStdCall: callingConvention = CallingConvention.StdCall; break; case MethodImportAttributes.CallingConventionThisCall: callingConvention = CallingConvention.ThisCall; break; case MethodImportAttributes.CallingConventionWinApi: callingConvention = CallingConvention.Winapi; break; default: throw new NotSupportedException("unknown calling convention"); } if (callingConvention != CallingConvention.Winapi) { var callingConventionType = FindInteropType(nameof(CallingConvention)); dllImport.AddNamedArg("CallingConvention", callingConventionType, (int)callingConvention); } CharSet charSet = CharSet.None; switch (info.Attributes & MethodImportAttributes.CharSetMask) { case MethodImportAttributes.CharSetAnsi: charSet = CharSet.Ansi; break; case MethodImportAttributes.CharSetAuto: charSet = CharSet.Auto; break; case MethodImportAttributes.CharSetUnicode: charSet = CharSet.Unicode; break; } if (charSet != CharSet.None) { var charSetType = FindInteropType(nameof(CharSet)); dllImport.AddNamedArg("CharSet", charSetType, (int)charSet); } if (!info.Name.IsNil && info.Name != def.Name) { dllImport.AddNamedArg("EntryPoint", KnownTypeCode.String, metadata.GetString(info.Name)); } if ((info.Attributes & MethodImportAttributes.ExactSpelling) == MethodImportAttributes.ExactSpelling) { dllImport.AddNamedArg("ExactSpelling", KnownTypeCode.Boolean, true); } if ((implAttributes & MethodImplAttributes.PreserveSig) == MethodImplAttributes.PreserveSig) { implAttributes &= ~MethodImplAttributes.PreserveSig; } else { dllImport.AddNamedArg("PreserveSig", KnownTypeCode.Boolean, false); } if ((info.Attributes & MethodImportAttributes.SetLastError) == MethodImportAttributes.SetLastError) { dllImport.AddNamedArg("SetLastError", KnownTypeCode.Boolean, true); } if ((info.Attributes & MethodImportAttributes.ThrowOnUnmappableCharDisable) == MethodImportAttributes.ThrowOnUnmappableCharDisable) { dllImport.AddNamedArg("ThrowOnUnmappableChar", KnownTypeCode.Boolean, false); } if ((info.Attributes & MethodImportAttributes.ThrowOnUnmappableCharEnable) == MethodImportAttributes.ThrowOnUnmappableCharEnable) { dllImport.AddNamedArg("ThrowOnUnmappableChar", KnownTypeCode.Boolean, true); } b.Add(dllImport.Build()); } #endregion #region PreserveSigAttribute if (implAttributes == MethodImplAttributes.PreserveSig) { b.Add(KnownAttribute.PreserveSig); implAttributes = 0; } #endregion #region MethodImplAttribute if (implAttributes != 0) { b.Add(KnownAttribute.MethodImpl, new TopLevelTypeName("System.Runtime.CompilerServices", nameof(MethodImplOptions)), (int)implAttributes ); } #endregion b.Add(def.GetCustomAttributes(), symbolKind); b.AddSecurityAttributes(def.GetDeclarativeSecurityAttributes()); return(b.Build()); }