internal PEParameterSymbol( PEModuleSymbol moduleSymbol, PEMethodSymbol containingSymbol, int ordinal, MetadataDecoder.ParamInfo parameter, out bool isBad) : this(moduleSymbol, containingSymbol, ordinal, parameter.IsByRef, parameter.HasByRefBeforeCustomModifiers, parameter.Type, parameter.Handle, parameter.CustomModifiers, out isBad) { }
public CSharpDefinitionMap( PEModule module, IEnumerable<SemanticEdit> edits, MetadataDecoder metadataDecoder, SymbolMatcher mapToMetadata, SymbolMatcher mapToPrevious) : base(module, edits) { Debug.Assert(mapToMetadata != null); Debug.Assert(metadataDecoder != null); this.mapToMetadata = mapToMetadata; this.mapToPrevious = mapToPrevious ?? mapToMetadata; this.metadataDecoder = metadataDecoder; }
public DefinitionMap( PEModule module, MetadataDecoder metadataDecoder, SymbolMatcher mapToMetadata, SymbolMatcher mapToPrevious, IReadOnlyDictionary<MethodSymbol, MethodDefinitionEntry> methodMap) { Debug.Assert(module != null); Debug.Assert(metadataDecoder != null); Debug.Assert(mapToMetadata != null); Debug.Assert(methodMap != null); this.module = module; this.metadataDecoder = metadataDecoder; this.mapToMetadata = mapToMetadata; this.mapToPrevious = mapToPrevious ?? mapToMetadata; this.methodMap = methodMap; }
internal static PEPropertySymbol Create( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, PropertyDefinitionHandle handle, PEMethodSymbol getMethod, PEMethodSymbol setMethod) { Debug.Assert((object)moduleSymbol != null); Debug.Assert((object)containingType != null); Debug.Assert(!handle.IsNil); var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType); SignatureHeader callingConvention; BadImageFormatException propEx; var propertyParams = metadataDecoder.GetSignatureForProperty(handle, out callingConvention, out propEx); Debug.Assert(propertyParams.Length > 0); var returnInfo = propertyParams[0]; PEPropertySymbol result; if (returnInfo.CustomModifiers.IsDefaultOrEmpty && returnInfo.RefCustomModifiers.IsDefaultOrEmpty) { result = new PEPropertySymbol(moduleSymbol, containingType, handle, getMethod, setMethod, 0, propertyParams, metadataDecoder); } else { result = new PEPropertySymbolWithCustomModifiers(moduleSymbol, containingType, handle, getMethod, setMethod, propertyParams, metadataDecoder); } if (propEx != null) { result._lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, result); } return result; }
private static ImmutableArray<ParameterSymbol> GetParameters( PEModuleSymbol moduleSymbol, PEPropertySymbol property, MetadataDecoder.ParamInfo[] propertyParams, MetadataDecoder.ParamInfo[] accessorParams, out bool anyParameterIsBad) { anyParameterIsBad = false; // First parameter is the property type. if (propertyParams.Length < 2) { return ImmutableArray<ParameterSymbol>.Empty; } var numAccessorParams = accessorParams.Length; var parameters = new ParameterSymbol[propertyParams.Length - 1]; for (int i = 1; i < propertyParams.Length; i++) // from 1 to skip property/return type { // NOTE: this is a best guess at the Dev10 behavior. The actual behavior is // in the unmanaged helper code that Dev10 uses to load the metadata. var propertyParam = propertyParams[i]; var paramHandle = i < numAccessorParams ? accessorParams[i].Handle : propertyParam.Handle; var ordinal = i - 1; bool isBad; parameters[ordinal] = new PEParameterSymbol(moduleSymbol, property, ordinal, paramHandle, propertyParam, out isBad); if (isBad) { anyParameterIsBad = true; } } return parameters.AsImmutableOrNull(); }
// internal for testing internal static IReadOnlyDictionary <SynthesizedDelegateKey, SynthesizedDelegateValue> GetSynthesizedDelegateMapFromMetadata(MetadataReader reader, MetadataDecoder metadataDecoder) { var result = new Dictionary <SynthesizedDelegateKey, SynthesizedDelegateValue>(); foreach (var handle in reader.TypeDefinitions) { var def = reader.GetTypeDefinition(handle); if (!def.Namespace.IsNil) { continue; } if (!reader.StringComparer.StartsWith(def.Name, GeneratedNames.ActionDelegateNamePrefix) && !reader.StringComparer.StartsWith(def.Name, GeneratedNames.FuncDelegateNamePrefix)) { continue; } // The name of a synthesized delegate neatly encodes everything we need to identify it, either // in the prefix (return void or not) or the name (ref kinds and arity) so we don't need anything // fancy for a key. var metadataName = reader.GetString(def.Name); var key = new SynthesizedDelegateKey(metadataName); var type = (NamedTypeSymbol)metadataDecoder.GetTypeOfToken(handle); var value = new SynthesizedDelegateValue(type.GetCciAdapter()); result.Add(key, value); } return(result); }
public void LocalTypeMetadata_Simple() { string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: ImportedFromTypeLib(""GeneralPIA.dll"")] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58258"")] public interface ITest1 { } public struct Test2 : ITest1 { } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58259"")] public interface ITest3 : ITest1 { void M2(); } public interface ITest4 { } [System.Serializable()] [StructLayout( LayoutKind.Explicit, CharSet =CharSet.Unicode, Pack = 16, Size = 64)] public struct Test5 { [FieldOffset(2)] public int F5; } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58260"")] public interface ITest6 { } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58261"")] public interface ITest7 { } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58262"")] public interface ITest8 { } public enum Test9 { F1 = 1, F2 = 2 } [StructLayout(LayoutKind.Sequential)] public struct Test10 { [NonSerialized()] public int F3; [MarshalAs(UnmanagedType.U4)] public int F4; } public delegate void Test11(); [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58264"")] public interface ITest13 { void M13(int x, __arglist); } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58265"")] public interface ITest14 { void M14(); int P6 { set; } event System.Action E4; } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58266"")] public interface ITest15 : ITest14 { } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58267"")] public interface ITest16 { void M16(); } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58268"")] public interface ITest17 { void M17(); void _VtblGap(); void M18(); void _VtblGap3_2(); void M19(); void _VtblGap4_2(); } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58269"")] public interface ITest18 { void _VtblGap3_2(); } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58270"")] public interface ITest19 { string M20(ref int x, out int y, [In()] ref int z, [In(), Out()] ref int u, [Optional()] int v, int w = 34); [return: MarshalAs(UnmanagedType.LPWStr)] string M21([MarshalAs(UnmanagedType.U4)] int x); } public struct Test20 { } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58271"")] public interface ITest21 { [SpecialName()] int P1 { get; set; } } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58272"")] public interface ITest22 { int P2 { get; set; } } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58273"")] public interface ITest23 { int P3 { get; } } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58274"")] public interface ITest24 { int P4 { set; } event System.Action E3; void M27(); } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58275"")] public interface ITest25 { [SpecialName()] event System.Action E1; } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58276"")] public interface ITest26 { event System.Action E2; int P5 { set; } void M26(); } "; var piaCompilation = CreateCompilationWithMscorlib(pia, options: TestOptions.ReleaseDll, assemblyName: "Pia"); CompileAndVerify(piaCompilation); string consumer = @" class UsePia { public static void Main() { Test2 x = new Test2(); ITest3 y = null; System.Console.WriteLine(x); System.Console.WriteLine(y); Test5 x5 = new Test5(); System.Console.WriteLine(x5); } [MyAttribute(typeof(ITest7))] void M2(ITest6 x) {} } class UsePia1 : ITest8 {} class MyAttribute : System.Attribute { public MyAttribute(System.Type type) { } } class UsePia2 { void Test(Test10 x, Test11 x11) { System.Console.WriteLine(Test9.F1); System.Console.WriteLine(x.F4); ITest17 y = null; y.M17(); y.M19(); } } class UsePia3 : ITest13 { public void M13(int x, __arglist) { } public void M14(ITest13 x) { x.M13(1, __arglist(2,3,4)); x.M13(1, __arglist((Test20[])null)); } } interface IUsePia4 : ITest15, ITest16, ITest18, ITest19 { } class UsePia4 { public int M1(ITest21 x) { return x.P1; } public void M2(ITest22 x) { x.P2 = 1; } public int M3(ITest23 x) { return x.P3; } public void M4(ITest24 x) { x.P4 = 1; } public void M5(ITest25 x) { x.E1 += null; } public void M6(ITest26 x) { x.E2 -= null; } } "; var compilation1 = CreateCompilationWithMscorlib(consumer, options: TestOptions.ReleaseExe, references: new MetadataReference[] { new CSharpCompilationReference(piaCompilation, embedInteropTypes: true) }); var compilation2 = CreateCompilationWithMscorlib(consumer, options: TestOptions.ReleaseExe, references: new MetadataReference[] { piaCompilation.EmitToImageReference(embedInteropTypes: true) }); System.Action<ModuleSymbol> metadataValidator = delegate (ModuleSymbol module) { ((PEModuleSymbol)module).Module.PretendThereArentNoPiaLocalTypes(); Assert.Equal(1, module.GetReferencedAssemblySymbols().Length); var itest1 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest1").Single(); Assert.Equal(TypeKind.Interface, itest1.TypeKind); Assert.Null(itest1.BaseType); Assert.Equal(0, itest1.Interfaces.Length); Assert.True(itest1.IsComImport); Assert.False(itest1.IsSerializable); Assert.False(itest1.IsSealed); Assert.Equal(System.Runtime.InteropServices.CharSet.Ansi, itest1.MarshallingCharSet); Assert.Equal(System.Runtime.InteropServices.LayoutKind.Auto, itest1.Layout.Kind); Assert.Equal(0, itest1.Layout.Alignment); Assert.Equal(0, itest1.Layout.Size); var attributes = itest1.GetAttributes(); Assert.Equal(3, attributes.Length); Assert.Equal("System.Runtime.CompilerServices.CompilerGeneratedAttribute", attributes[0].ToString()); Assert.Equal(@"System.Runtime.InteropServices.GuidAttribute(""f9c2d51d-4f44-45f0-9eda-c9d599b58258"")", attributes[1].ToString()); Assert.Equal("System.Runtime.InteropServices.TypeIdentifierAttribute", attributes[2].ToString()); // TypDefName: ITest1 (02000018) // Flags : [Public] [AutoLayout] [Interface] [Abstract] [Import] [AnsiClass] (000010a1) Assert.Equal(TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Import | TypeAttributes.AnsiClass, itest1.Flags); var test2 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("Test2").Single(); Assert.Equal(TypeKind.Struct, test2.TypeKind); Assert.Equal(SpecialType.System_ValueType, test2.BaseType.SpecialType); Assert.Same(itest1, test2.Interfaces.Single()); Assert.False(test2.IsComImport); Assert.False(test2.IsSerializable); Assert.True(test2.IsSealed); Assert.Equal(System.Runtime.InteropServices.CharSet.Ansi, test2.MarshallingCharSet); Assert.Equal(System.Runtime.InteropServices.LayoutKind.Sequential, test2.Layout.Kind); Assert.Equal(0, test2.Layout.Alignment); Assert.Equal(1, test2.Layout.Size); // TypDefName: Test2 (02000013) // Flags : [Public] [SequentialLayout] [Class] [Sealed] [AnsiClass] [BeforeFieldInit] (00100109) Assert.Equal(TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, test2.Flags); attributes = test2.GetAttributes(); Assert.Equal(2, attributes.Length); Assert.Equal("System.Runtime.CompilerServices.CompilerGeneratedAttribute", attributes[0].ToString()); Assert.Equal(@"System.Runtime.InteropServices.TypeIdentifierAttribute(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"", ""Test2"")", attributes[1].ToString()); var itest3 = module.GlobalNamespace.GetTypeMembers("ITest3").Single(); Assert.Equal(TypeKind.Interface, itest3.TypeKind); Assert.Same(itest1, itest3.Interfaces.Single()); Assert.True(itest3.IsComImport); Assert.False(itest3.IsSerializable); Assert.False(itest3.IsSealed); Assert.Equal(System.Runtime.InteropServices.CharSet.Ansi, itest3.MarshallingCharSet); Assert.Equal(System.Runtime.InteropServices.LayoutKind.Auto, itest3.Layout.Kind); Assert.Equal(0, itest3.Layout.Alignment); Assert.Equal(0, itest3.Layout.Size); Assert.Equal(0, module.GlobalNamespace.GetTypeMembers("ITest4").Length); var test5 = module.GlobalNamespace.GetTypeMembers("Test5").Single(); Assert.Equal(TypeKind.Struct, test5.TypeKind); Assert.False(test5.IsComImport); Assert.True(test5.IsSerializable); Assert.True(test5.IsSealed); Assert.Equal(System.Runtime.InteropServices.CharSet.Unicode, test5.MarshallingCharSet); Assert.Equal(System.Runtime.InteropServices.LayoutKind.Explicit, test5.Layout.Kind); Assert.Equal(16, test5.Layout.Alignment); Assert.Equal(64, test5.Layout.Size); var f5 = (PEFieldSymbol)test5.GetMembers()[0]; Assert.Equal("System.Int32 Test5.F5", f5.ToTestDisplayString()); Assert.Equal(2, f5.TypeLayoutOffset.Value); // Field Name: F5 (04000003) // Flags : [Public] (00000006) Assert.Equal(FieldAttributes.Public, f5.Flags); var itest6 = module.GlobalNamespace.GetTypeMembers("ITest6").Single(); Assert.Equal(TypeKind.Interface, itest6.TypeKind); var itest7 = module.GlobalNamespace.GetTypeMembers("ITest7").Single(); Assert.Equal(TypeKind.Interface, itest7.TypeKind); var itest8 = module.GlobalNamespace.GetTypeMembers("ITest8").Single(); Assert.Equal(TypeKind.Interface, itest8.TypeKind); Assert.Same(itest8, module.GlobalNamespace.GetTypeMembers("UsePia1").Single().Interfaces.Single()); var test9 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("Test9").Single(); Assert.Equal(TypeKind.Enum, test9.TypeKind); Assert.False(test9.IsComImport); Assert.False(test9.IsSerializable); Assert.True(test9.IsSealed); Assert.Equal(System.Runtime.InteropServices.CharSet.Ansi, test9.MarshallingCharSet); Assert.Equal(System.Runtime.InteropServices.LayoutKind.Auto, test9.Layout.Kind); Assert.Equal(SpecialType.System_Int32, test9.EnumUnderlyingType.SpecialType); // TypDefName: Test9 (02000016) // Flags : [Public] [AutoLayout] [Class] [Sealed] [AnsiClass] (00000101) Assert.Equal(TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AnsiClass, test9.Flags); attributes = test9.GetAttributes(); Assert.Equal(2, attributes.Length); Assert.Equal("System.Runtime.CompilerServices.CompilerGeneratedAttribute", attributes[0].ToString()); Assert.Equal(@"System.Runtime.InteropServices.TypeIdentifierAttribute(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"", ""Test9"")", attributes[1].ToString()); var fieldToEmit = test9.GetFieldsToEmit().ToArray().AsImmutableOrNull(); Assert.Equal(3, fieldToEmit.Length); var value__ = (PEFieldSymbol)fieldToEmit[0]; Assert.Equal(Accessibility.Public, value__.DeclaredAccessibility); Assert.Equal("System.Int32 Test9.value__", value__.ToTestDisplayString()); Assert.False(value__.IsStatic); Assert.True(value__.HasSpecialName); Assert.True(value__.HasRuntimeSpecialName); Assert.Null(value__.ConstantValue); // Field Name: value__ (04000004) // Flags : [Public] [SpecialName] [RTSpecialName] (00000606) Assert.Equal(FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName, value__.Flags); var f1 = (PEFieldSymbol)fieldToEmit[1]; Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal("Test9.F1", f1.ToTestDisplayString()); Assert.True(f1.IsStatic); Assert.False(f1.HasSpecialName); Assert.False(f1.HasRuntimeSpecialName); Assert.Equal(1, f1.ConstantValue); // Field Name: F1 (04000005) // Flags : [Public] [Static] [Literal] [HasDefault] (00008056) Assert.Equal(FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal | FieldAttributes.HasDefault, f1.Flags); var f2 = (FieldSymbol)fieldToEmit[2]; Assert.Equal("Test9.F2", f2.ToTestDisplayString()); Assert.Equal(2, f2.ConstantValue); Assert.Equal(3, test9.GetMembers().Length); Assert.Same(f1, test9.GetMembers()[0]); Assert.Same(f2, test9.GetMembers()[1]); Assert.True(((MethodSymbol)test9.GetMembers()[2]).IsDefaultValueTypeConstructor()); var test10 = module.GlobalNamespace.GetTypeMembers("Test10").Single(); Assert.Equal(TypeKind.Struct, test10.TypeKind); Assert.Equal(System.Runtime.InteropServices.LayoutKind.Sequential, test10.Layout.Kind); Assert.Equal(3, test10.GetMembers().Length); var f3 = (FieldSymbol)test10.GetMembers()[0]; Assert.Equal(Accessibility.Public, f3.DeclaredAccessibility); Assert.Equal("System.Int32 Test10.F3", f3.ToTestDisplayString()); Assert.False(f3.IsStatic); Assert.False(f3.HasSpecialName); Assert.False(f3.HasRuntimeSpecialName); Assert.Null(f3.ConstantValue); Assert.Equal((System.Runtime.InteropServices.UnmanagedType)0, f3.MarshallingType); Assert.False(f3.TypeLayoutOffset.HasValue); Assert.True(f3.IsNotSerialized); var f4 = (FieldSymbol)test10.GetMembers()[1]; Assert.Equal("System.Int32 Test10.F4", f4.ToTestDisplayString()); Assert.Equal(System.Runtime.InteropServices.UnmanagedType.U4, f4.MarshallingType); Assert.False(f4.IsNotSerialized); Assert.True(((MethodSymbol)test10.GetMembers()[2]).IsDefaultValueTypeConstructor()); var test11 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("Test11").Single(); Assert.Equal(TypeKind.Delegate, test11.TypeKind); Assert.Equal(SpecialType.System_MulticastDelegate, test11.BaseType.SpecialType); // TypDefName: Test11 (02000012) // Flags : [Public] [AutoLayout] [Class] [Sealed] [AnsiClass] (00000101) Assert.Equal(TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AnsiClass, test11.Flags); attributes = test11.GetAttributes(); Assert.Equal(2, attributes.Length); Assert.Equal("System.Runtime.CompilerServices.CompilerGeneratedAttribute", attributes[0].ToString()); Assert.Equal(@"System.Runtime.InteropServices.TypeIdentifierAttribute(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"", ""Test11"")", attributes[1].ToString()); Assert.Equal(4, test11.GetMembers().Length); var ctor = (PEMethodSymbol)test11.GetMembers(".ctor").Single(); // MethodName: .ctor (0600000F) // Flags : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor] (00001886) // ImplFlags : [Runtime] [Managed] (00000003) // CallCnvntn: [DEFAULT] // hasThis // ReturnType: Void // 2 Arguments // Argument #1: Object // Argument #2: I Assert.Equal(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, ctor.Flags); Assert.Equal(MethodImplAttributes.Runtime, (MethodImplAttributes)ctor.ImplementationAttributes); Assert.Equal(CallingConvention.Default | CallingConvention.HasThis, ctor.CallingConvention); Assert.Equal("Test11..ctor(System.Object @object, System.IntPtr method)", ctor.ToTestDisplayString()); var begin = (PEMethodSymbol)test11.GetMembers("BeginInvoke").Single(); // MethodName: BeginInvoke (06000011) // Flags : [Public] [Virtual] [HideBySig] [NewSlot] (000001c6) // ImplFlags : [Runtime] [Managed] (00000003) // CallCnvntn: [DEFAULT] // hasThis // ReturnType: Class System.IAsyncResult // 2 Arguments // Argument #1: Class System.AsyncCallback // Argument #2: Object Assert.Equal(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot, begin.Flags); Assert.Equal(MethodImplAttributes.Runtime, (MethodImplAttributes)begin.ImplementationAttributes); Assert.Equal(CallingConvention.Default | CallingConvention.HasThis, begin.CallingConvention); Assert.Equal("System.IAsyncResult Test11.BeginInvoke(System.AsyncCallback callback, System.Object @object)", begin.ToTestDisplayString()); var end = (PEMethodSymbol)test11.GetMembers("EndInvoke").Single(); // MethodName: EndInvoke (06000012) // Flags : [Public] [Virtual] [HideBySig] [NewSlot] (000001c6) // ImplFlags : [Runtime] [Managed] (00000003) // CallCnvntn: [DEFAULT] // hasThis // ReturnType: Void // 1 Arguments // Argument #1: Class System.IAsyncResult Assert.Equal(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot, end.Flags); Assert.Equal(MethodImplAttributes.Runtime, (MethodImplAttributes)end.ImplementationAttributes); Assert.Equal(CallingConvention.Default | CallingConvention.HasThis, end.CallingConvention); Assert.Equal("void Test11.EndInvoke(System.IAsyncResult result)", end.ToTestDisplayString()); var invoke = (PEMethodSymbol)test11.GetMembers("Invoke").Single(); // MethodName: Invoke (06000010) // Flags : [Public] [Virtual] [HideBySig] [NewSlot] (000001c6) // ImplFlags : [Runtime] [Managed] (00000003) // CallCnvntn: [DEFAULT] // hasThis // ReturnType: Void // No arguments. Assert.Equal(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot, invoke.Flags); Assert.Equal(MethodImplAttributes.Runtime, (MethodImplAttributes)invoke.ImplementationAttributes); Assert.Equal(CallingConvention.Default | CallingConvention.HasThis, invoke.CallingConvention); Assert.Equal("void Test11.Invoke()", invoke.ToTestDisplayString()); var itest13 = module.GlobalNamespace.GetTypeMembers("ITest13").Single(); Assert.Equal(TypeKind.Interface, itest13.TypeKind); var m13 = (PEMethodSymbol)itest13.GetMembers()[0]; // MethodName: M13 (06000001) // Flags : [Public] [Virtual] [HideBySig] [NewSlot] [Abstract] (000005c6) // ImplFlags : [IL] [Managed] (00000000) // CallCnvntn: [VARARG] // hasThis // ReturnType: Void // 1 Arguments // Argument #1: I4 // 1 Parameters // (1) ParamToken : (08000001) Name : x flags: [none] (00000000) Assert.Equal(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Abstract, m13.Flags); Assert.Equal(MethodImplAttributes.IL, (MethodImplAttributes)m13.ImplementationAttributes); Assert.Equal(CallingConvention.ExtraArguments | CallingConvention.HasThis, m13.CallingConvention); Assert.Equal("void ITest13.M13(System.Int32 x, __arglist)", m13.ToTestDisplayString()); var itest14 = module.GlobalNamespace.GetTypeMembers("ITest14").Single(); Assert.Equal(TypeKind.Interface, itest14.TypeKind); Assert.Equal(6, itest14.GetMembers().Length); Assert.Equal("void ITest14.M14()", itest14.GetMembers()[0].ToTestDisplayString()); Assert.Equal("void ITest14.P6.set", itest14.GetMembers()[1].ToTestDisplayString()); Assert.Equal("void ITest14.E4.add", itest14.GetMembers()[2].ToTestDisplayString()); Assert.Equal("void ITest14.E4.remove", itest14.GetMembers()[3].ToTestDisplayString()); Assert.Equal("System.Int32 ITest14.P6 { set; }", itest14.GetMembers()[4].ToTestDisplayString()); Assert.Equal("event System.Action ITest14.E4", itest14.GetMembers()[5].ToTestDisplayString()); var itest16 = module.GlobalNamespace.GetTypeMembers("ITest16").Single(); Assert.Equal(TypeKind.Interface, itest16.TypeKind); Assert.Equal("void ITest16.M16()", itest16.GetMembers()[0].ToTestDisplayString()); var itest17 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest17").Single(); Assert.Equal(TypeKind.Interface, itest17.TypeKind); var metadata = ((PEModuleSymbol)module).Module; var methodNames = metadata.GetMethodsOfTypeOrThrow(itest17.Handle).AsEnumerable().Select(rid => metadata.GetMethodDefNameOrThrow(rid)).ToArray(); Assert.Equal(3, methodNames.Length); Assert.Equal("M17", methodNames[0]); Assert.Equal("_VtblGap1_4", methodNames[1]); Assert.Equal("M19", methodNames[2]); MethodDefinitionHandle gapMethodDef = metadata.GetMethodsOfTypeOrThrow(itest17.Handle).AsEnumerable().ElementAt(1); string name; MethodImplAttributes implFlags; MethodAttributes flags; int rva; metadata.GetMethodDefPropsOrThrow(gapMethodDef, out name, out implFlags, out flags, out rva); Assert.Equal(MethodAttributes.Public | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, flags); Assert.Equal(MethodImplAttributes.IL | MethodImplAttributes.Runtime, implFlags); SignatureHeader signatureHeader; BadImageFormatException mrEx; ParamInfo<TypeSymbol>[] paramInfo = new MetadataDecoder((PEModuleSymbol)module, itest17).GetSignatureForMethod(gapMethodDef, out signatureHeader, out mrEx, allowByRefReturn: true); Assert.Null(mrEx); Assert.Equal((byte)SignatureCallingConvention.Default | (byte)SignatureAttributes.Instance, signatureHeader.RawValue); Assert.Equal(1, paramInfo.Length); Assert.Equal(SpecialType.System_Void, paramInfo[0].Type.SpecialType); Assert.False(paramInfo[0].IsByRef); Assert.True(paramInfo[0].CustomModifiers.IsDefault); Assert.Equal(2, itest17.GetMembers().Length); var m17 = (PEMethodSymbol)itest17.GetMembers("M17").Single(); // MethodName: M17 (06000013) // Flags : [Public] [Virtual] [HideBySig] [NewSlot] [Abstract] (000005c6) // ImplFlags : [IL] [Managed] (00000000) // CallCnvntn: [DEFAULT] // hasThis // ReturnType: Void // No arguments. Assert.Equal(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Abstract, m17.Flags); Assert.Equal(MethodImplAttributes.IL, (MethodImplAttributes)m17.ImplementationAttributes); Assert.Equal(CallingConvention.Default | CallingConvention.HasThis, m17.CallingConvention); Assert.Equal("void ITest17.M17()", m17.ToTestDisplayString()); var itest18 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest18").Single(); Assert.Equal(TypeKind.Interface, itest18.TypeKind); Assert.False(metadata.GetMethodsOfTypeOrThrow(itest18.Handle).AsEnumerable().Any()); var itest19 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest19").Single(); var m20 = (PEMethodSymbol)itest19.GetMembers("M20").Single(); // 6 Arguments // Argument #1: ByRef I4 // Argument #2: ByRef I4 // Argument #3: ByRef I4 // Argument #4: ByRef I4 // Argument #5: I4 // Argument #6: I4 // 6 Parameters // (1) ParamToken : (08000008) Name : x flags: [none] (00000000) // (2) ParamToken : (08000009) Name : y flags: [Out] (00000002) // (3) ParamToken : (0800000a) Name : z flags: [In] (00000001) // (4) ParamToken : (0800000b) Name : u flags: [In] [Out] (00000003) // (5) ParamToken : (0800000c) Name : v flags: [Optional] (00000010) // (6) ParamToken : (0800000d) Name : w flags: [Optional] [HasDefault] (00001010) Default: (I4) 34 var param = (PEParameterSymbol)m20.Parameters[0]; Assert.Equal(RefKind.Ref, param.RefKind); Assert.Equal((ParameterAttributes)0, param.Flags); param = (PEParameterSymbol)m20.Parameters[1]; Assert.Equal(RefKind.Out, param.RefKind); Assert.Equal(ParameterAttributes.Out, param.Flags); param = (PEParameterSymbol)m20.Parameters[2]; Assert.Equal(RefKind.Ref, param.RefKind); Assert.Equal(ParameterAttributes.In, param.Flags); param = (PEParameterSymbol)m20.Parameters[3]; Assert.Equal(RefKind.Ref, param.RefKind); Assert.Equal(ParameterAttributes.In | ParameterAttributes.Out, param.Flags); param = (PEParameterSymbol)m20.Parameters[4]; Assert.Equal(RefKind.None, param.RefKind); Assert.Equal(ParameterAttributes.Optional, param.Flags); Assert.Null(param.ExplicitDefaultConstantValue); param = (PEParameterSymbol)m20.Parameters[5]; Assert.Equal(RefKind.None, param.RefKind); Assert.Equal(ParameterAttributes.Optional | ParameterAttributes.HasDefault, param.Flags); Assert.Equal(34, param.ExplicitDefaultValue); param = m20.ReturnTypeParameter; Assert.Equal((ParameterAttributes)0, param.Flags); var m21 = (PEMethodSymbol)itest19.GetMembers("M21").Single(); // 1 Arguments // Argument #1: I4 // 2 Parameters // (0) ParamToken : (0800000e) Name : flags: [HasFieldMarshal] (00002000) // NATIVE_TYPE_LPWSTR // (1) ParamToken : (0800000f) Name : x flags: [HasFieldMarshal] (00002000) // NATIVE_TYPE_U4 param = (PEParameterSymbol)m21.Parameters[0]; Assert.Equal(ParameterAttributes.HasFieldMarshal, param.Flags); Assert.Equal(System.Runtime.InteropServices.UnmanagedType.U4, (System.Runtime.InteropServices.UnmanagedType)param.MarshallingDescriptor[0]); param = m21.ReturnTypeParameter; Assert.Equal(ParameterAttributes.HasFieldMarshal, param.Flags); Assert.Equal(System.Runtime.InteropServices.UnmanagedType.LPWStr, (System.Runtime.InteropServices.UnmanagedType)param.MarshallingDescriptor[0]); var itest21 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest21").Single(); var p1 = (PEPropertySymbol)itest21.GetMembers("P1").Single(); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.True(p1.HasSpecialName); Assert.False(p1.HasRuntimeSpecialName); var get_P1 = (PEMethodSymbol)itest21.GetMembers("get_P1").Single(); var set_P1 = (PEMethodSymbol)itest21.GetMembers("set_P1").Single(); Assert.Same(p1.GetMethod, get_P1); Assert.Same(p1.SetMethod, set_P1); var itest22 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest22").Single(); var p2 = (PEPropertySymbol)itest22.GetMembers("P2").Single(); var get_P2 = (PEMethodSymbol)itest22.GetMembers("get_P2").Single(); var set_P2 = (PEMethodSymbol)itest22.GetMembers("set_P2").Single(); Assert.Same(p2.GetMethod, get_P2); Assert.Same(p2.SetMethod, set_P2); var itest23 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest23").Single(); var p3 = (PEPropertySymbol)itest23.GetMembers("P3").Single(); var get_P3 = (PEMethodSymbol)itest23.GetMembers("get_P3").Single(); Assert.Same(p3.GetMethod, get_P3); Assert.Null(p3.SetMethod); var itest24 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest24").Single(); var p4 = (PEPropertySymbol)itest24.GetMembers("P4").Single(); Assert.Equal(2, itest24.GetMembers().Length); Assert.False(p4.HasSpecialName); Assert.False(p4.HasRuntimeSpecialName); Assert.Equal((byte)SignatureKind.Property | (byte)SignatureAttributes.Instance, (byte)p4.CallingConvention); var set_P4 = (PEMethodSymbol)itest24.GetMembers("set_P4").Single(); Assert.Null(p4.GetMethod); Assert.Same(p4.SetMethod, set_P4); var itest25 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest25").Single(); var e1 = (PEEventSymbol)itest25.GetMembers("E1").Single(); Assert.True(e1.HasSpecialName); Assert.False(e1.HasRuntimeSpecialName); var add_E1 = (PEMethodSymbol)itest25.GetMembers("add_E1").Single(); var remove_E1 = (PEMethodSymbol)itest25.GetMembers("remove_E1").Single(); Assert.Same(e1.AddMethod, add_E1); Assert.Same(e1.RemoveMethod, remove_E1); var itest26 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest26").Single(); var e2 = (PEEventSymbol)itest26.GetMembers("E2").Single(); Assert.Equal(3, itest26.GetMembers().Length); Assert.False(e2.HasSpecialName); Assert.False(e2.HasRuntimeSpecialName); var add_E2 = (PEMethodSymbol)itest26.GetMembers("add_E2").Single(); var remove_E2 = (PEMethodSymbol)itest26.GetMembers("remove_E2").Single(); Assert.Same(e2.AddMethod, add_E2); Assert.Same(e2.RemoveMethod, remove_E2); }; var expected_M5 = @" { // Code size 8 (0x8) .maxstack 2 IL_0000: ldarg.1 IL_0001: ldnull IL_0002: callvirt ""void ITest25.E1.add"" IL_0007: ret } "; var expected_M6 = @" { // Code size 8 (0x8) .maxstack 2 IL_0000: ldarg.1 IL_0001: ldnull IL_0002: callvirt ""void ITest26.E2.remove"" IL_0007: ret } "; var verifier = CompileAndVerify(compilation1, symbolValidator: metadataValidator); verifier.VerifyIL("UsePia4.M5", expected_M5); verifier.VerifyIL("UsePia4.M6", expected_M6); verifier = CompileAndVerify(compilation2, symbolValidator: metadataValidator); verifier.VerifyIL("UsePia4.M5", expected_M5); verifier.VerifyIL("UsePia4.M6", expected_M6); }
/// <summary> /// </summary> /// <param name="localInfo"> /// </param> /// <param name="index"> /// </param> /// <param name="genericContext"> /// </param> internal MetadataLocalVariableAdapter( MetadataDecoder<TypeSymbol, MethodSymbol, FieldSymbol, AssemblySymbol, Symbol>.LocalInfo localInfo, int index, IGenericContext genericContext) : this(localInfo, index) { this.GenericContext = genericContext; }
private PEPropertySymbol( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, PropertyDefinitionHandle handle, PEMethodSymbol getMethod, PEMethodSymbol setMethod, int countOfCustomModifiers, ParamInfo<TypeSymbol>[] propertyParams, MetadataDecoder metadataDecoder) { _containingType = containingType; var module = moduleSymbol.Module; PropertyAttributes mdFlags = 0; BadImageFormatException mrEx = null; try { module.GetPropertyDefPropsOrThrow(handle, out _name, out mdFlags); } catch (BadImageFormatException e) { mrEx = e; if ((object)_name == null) { _name = string.Empty; } } _getMethod = getMethod; _setMethod = setMethod; _handle = handle; SignatureHeader unusedCallingConvention; BadImageFormatException getEx = null; var getMethodParams = (object)getMethod == null ? null : metadataDecoder.GetSignatureForMethod(getMethod.Handle, out unusedCallingConvention, out getEx); BadImageFormatException setEx = null; var setMethodParams = (object)setMethod == null ? null : metadataDecoder.GetSignatureForMethod(setMethod.Handle, out unusedCallingConvention, out setEx); // NOTE: property parameter names are not recorded in metadata, so we have to // use the parameter names from one of the indexers // NB: prefer setter names to getter names if both are present. bool isBad; _parameters = GetParameters(moduleSymbol, this, propertyParams, setMethodParams ?? getMethodParams, out isBad); if (getEx != null || setEx != null || mrEx != null || isBad) { _lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this); } var returnInfo = propertyParams[0]; _refKind = returnInfo.IsByRef ? RefKind.Ref : RefKind.None; // CONSIDER: Can we make parameter type computation lazy? TypeSymbol originalPropertyType = returnInfo.Type; _propertyType = DynamicTypeDecoder.TransformType(originalPropertyType, countOfCustomModifiers, handle, moduleSymbol, _refKind); // Dynamify object type if necessary _propertyType = _propertyType.AsDynamicIfNoPia(_containingType); _propertyType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(_propertyType, handle, moduleSymbol); // A property is bogus and must be accessed by calling its accessors directly if the // accessor signatures do not agree, both with each other and with the property, // or if it has parameters and is not an indexer or indexed property. bool callMethodsDirectly = !DoSignaturesMatch(module, metadataDecoder, propertyParams, _getMethod, getMethodParams, _setMethod, setMethodParams) || MustCallMethodsDirectlyCore(); if (!callMethodsDirectly) { if ((object)_getMethod != null) { _getMethod.SetAssociatedProperty(this, MethodKind.PropertyGet); } if ((object)_setMethod != null) { _setMethod.SetAssociatedProperty(this, MethodKind.PropertySet); } } if (callMethodsDirectly) { _flags |= Flags.CallMethodsDirectly; } if ((mdFlags & PropertyAttributes.SpecialName) != 0) { _flags |= Flags.IsSpecialName; } if ((mdFlags & PropertyAttributes.RTSpecialName) != 0) { _flags |= Flags.IsRuntimeSpecialName; } }
/// <summary> /// Create a context for evaluating expressions within a method scope. /// </summary> /// <param name="previous">Previous context, if any, for possible re-use.</param> /// <param name="metadataBlocks">Module metadata</param> /// <param name="symReader"><see cref="ISymUnmanagedReader"/> for PDB associated with <paramref name="moduleVersionId"/></param> /// <param name="moduleVersionId">Module containing method</param> /// <param name="methodToken">Method metadata token</param> /// <param name="methodVersion">Method version.</param> /// <param name="ilOffset">IL offset of instruction pointer in method</param> /// <param name="localSignatureToken">Method local signature token</param> /// <returns>Evaluation context</returns> internal static EvaluationContext CreateMethodContext( CSharpMetadataContext previous, ImmutableArray <MetadataBlock> metadataBlocks, object symReader, Guid moduleVersionId, int methodToken, int methodVersion, int ilOffset, int localSignatureToken) { Debug.Assert(MetadataTokens.Handle(methodToken).Kind == HandleKind.MethodDefinition); var typedSymReader = (ISymUnmanagedReader)symReader; var scopes = ArrayBuilder <ISymUnmanagedScope> .GetInstance(); typedSymReader.GetScopes(methodToken, methodVersion, ilOffset, IsLocalScopeEndInclusive, scopes); var scope = scopes.GetMethodScope(methodToken, methodVersion); // Re-use the previous compilation if possible. CSharpCompilation compilation; if (metadataBlocks.HaveNotChanged(previous)) { // Re-use entire context if method scope has not changed. var previousContext = previous.EvaluationContext; if ((scope != null) && (previousContext != null) && scope.Equals(previousContext.MethodScope)) { return(previousContext); } compilation = previous.Compilation; } else { compilation = metadataBlocks.ToCompilation(); } var localNames = scopes.GetLocalNames(); var dynamicLocalMap = ImmutableDictionary <int, ImmutableArray <bool> > .Empty; var dynamicLocalConstantMap = ImmutableDictionary <string, ImmutableArray <bool> > .Empty; var inScopeHoistedLocalIndices = ImmutableSortedSet <int> .Empty; var methodDebugInfo = default(MethodDebugInfo); if (typedSymReader != null) { try { var cdi = typedSymReader.GetCustomDebugInfoBytes(methodToken, methodVersion); if (cdi != null) { CustomDebugInfoReader.GetCSharpDynamicLocalInfo( cdi, methodToken, methodVersion, localNames.FirstOrDefault(), out dynamicLocalMap, out dynamicLocalConstantMap); inScopeHoistedLocalIndices = CustomDebugInfoReader.GetCSharpInScopeHoistedLocalIndices( cdi, methodToken, methodVersion, ilOffset); } // TODO (acasey): switch on the type of typedSymReader and call the appropriate helper. (GH #702) methodDebugInfo = typedSymReader.GetMethodDebugInfo(methodToken, methodVersion); } catch (InvalidOperationException) { // bad CDI, ignore } } var methodHandle = (MethodDefinitionHandle)MetadataTokens.Handle(methodToken); var currentFrame = compilation.GetMethod(moduleVersionId, methodHandle); Debug.Assert((object)currentFrame != null); var metadataDecoder = new MetadataDecoder((PEModuleSymbol)currentFrame.ContainingModule, currentFrame); var localInfo = metadataDecoder.GetLocalInfo(localSignatureToken); var localBuilder = ArrayBuilder <LocalSymbol> .GetInstance(); var sourceAssembly = compilation.SourceAssembly; GetLocals(localBuilder, currentFrame, localNames, localInfo, dynamicLocalMap, sourceAssembly); GetConstants(localBuilder, currentFrame, scopes.GetConstantSignatures(), metadataDecoder, dynamicLocalConstantMap, sourceAssembly); scopes.Free(); var locals = localBuilder.ToImmutableAndFree(); return(new EvaluationContext( metadataBlocks, scope, compilation, metadataDecoder, currentFrame, locals, inScopeHoistedLocalIndices, methodDebugInfo)); }
public void AnonymousTypesWithNullables() { var source0 = @" using System; class C { static T id<T>(T t) => t; static T F<T>(Func<T> f) => f(); static void M(string? x) { var y1 = new { A = id(x) }; var y2 = F(() => new { B = id(x) }); var z = new Func<string>(() => y1.A + y2.B); } }"; var source1 = @" using System; class C { static T id<T>(T t) => t; static T F<T>(Func<T> f) => f(); static void M(string? x) { if (x is null) throw new Exception(); var y1 = new { A = id(x) }; var y2 = F(() => new { B = id(x) }); var z = new Func<string>(() => y1.A + y2.B); } }"; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll); var peRef0 = compilation0.EmitToImageReference(); var peAssemblySymbol0 = (PEAssemblySymbol)CreateCompilation("", new[] { peRef0 }).GetReferencedAssemblySymbol(peRef0); var peModule0 = (PEModuleSymbol)peAssemblySymbol0.Modules[0]; var reader0 = peModule0.Module.MetadataReader; var decoder0 = new MetadataDecoder(peModule0); var anonymousTypeMap0 = PEDeltaAssemblyBuilder.GetAnonymousTypeMapFromMetadata(reader0, decoder0); Assert.Equal("<>f__AnonymousType0", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("A", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType1", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("B", isKey: false, ignoreCase: false)))].Name); Assert.Equal(2, anonymousTypeMap0.Count); var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll); var testData = new CompilationTestData(); compilation1.EmitToArray(testData: testData); var peAssemblyBuilder = (PEAssemblyBuilder)testData.Module; var c = compilation1.GetMember <NamedTypeSymbol>("C"); var displayClass = peAssemblyBuilder.GetSynthesizedTypes(c).Single(); Assert.Equal("<>c__DisplayClass2_0", displayClass.Name); var emitContext = new EmitContext(peAssemblyBuilder, null, new DiagnosticBag(), metadataOnly: false, includePrivateMembers: true); var fields = displayClass.GetFields(emitContext).ToArray(); AssertEx.SetEqual(fields.Select(f => f.Name), new[] { "x", "y1", "y2" }); var y1 = fields.Where(f => f.Name == "y1").Single(); var y2 = fields.Where(f => f.Name == "y2").Single(); var matcher = new CSharpSymbolMatcher(anonymousTypeMap0, compilation1.SourceAssembly, emitContext, peAssemblySymbol0); var mappedY1 = (Cci.IFieldDefinition)matcher.MapDefinition(y1); var mappedY2 = (Cci.IFieldDefinition)matcher.MapDefinition(y2); Assert.Equal("y1", mappedY1.Name); Assert.Equal("y2", mappedY2.Name); }
public CSharpEESymbolProvider(SourceAssemblySymbol sourceAssembly, PEModuleSymbol module, PEMethodSymbol method) { _metadataDecoder = new MetadataDecoder(module, method); _sourceAssembly = sourceAssembly; _method = method; }
private void CompileTimeAndRuntimeAssemblies( ImmutableArray <MetadataReference> compileReferences, ImmutableArray <MetadataReference> runtimeReferences, string storageAssemblyName) { var source = @"class C { static void M(LibraryA.A a, LibraryB.B b, Windows.Data.Text.TextSegment t, Windows.Storage.StorageFolder f) { } }"; var runtime = CreateRuntime(source, compileReferences, runtimeReferences); var context = CreateMethodContext(runtime, "C.M"); string error; var testData = new CompilationTestData(); context.CompileExpression("(object)a ?? (object)b ?? (object)t ?? f", out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 17 (0x11) .maxstack 2 IL_0000: ldarg.0 IL_0001: dup IL_0002: brtrue.s IL_0010 IL_0004: pop IL_0005: ldarg.1 IL_0006: dup IL_0007: brtrue.s IL_0010 IL_0009: pop IL_000a: ldarg.2 IL_000b: dup IL_000c: brtrue.s IL_0010 IL_000e: pop IL_000f: ldarg.3 IL_0010: ret }"); testData = new CompilationTestData(); var result = context.CompileExpression("default(Windows.Storage.StorageFolder)", out error, testData); Assert.Null(error); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldnull IL_0001: ret }"); // Check return type is from runtime assembly. var assemblyReference = AssemblyMetadata.CreateFromImage(result.Assembly).GetReference(); var compilation = CSharpCompilation.Create( assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(), references: runtimeReferences.Concat(ImmutableArray.Create <MetadataReference>(assemblyReference))); var assembly = ImmutableArray.CreateRange(result.Assembly); using (var metadata = ModuleMetadata.CreateFromImage(ImmutableArray.CreateRange(assembly))) { var reader = metadata.MetadataReader; var typeDef = reader.GetTypeDef("<>x"); var methodHandle = reader.GetMethodDefHandle(typeDef, "<>m0"); var module = (PEModuleSymbol)compilation.GetMember("<>x").ContainingModule; var metadataDecoder = new MetadataDecoder(module); SignatureHeader signatureHeader; BadImageFormatException metadataException; var parameters = metadataDecoder.GetSignatureForMethod(methodHandle, out signatureHeader, out metadataException); Assert.Equal(parameters.Length, 5); var actualReturnType = parameters[0].Type; Assert.Equal(actualReturnType.TypeKind, TypeKind.Class); // not error var expectedReturnType = compilation.GetMember("Windows.Storage.StorageFolder"); Assert.Equal(expectedReturnType, actualReturnType); Assert.Equal(storageAssemblyName, actualReturnType.ContainingAssembly.Name); } }
// internal for testing internal static IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> GetAnonymousTypeMapFromMetadata(MetadataReader reader, MetadataDecoder metadataDecoder) { var result = new Dictionary <AnonymousTypeKey, AnonymousTypeValue>(); foreach (var handle in reader.TypeDefinitions) { var def = reader.GetTypeDefinition(handle); if (!def.Namespace.IsNil) { continue; } if (!reader.StringComparer.StartsWith(def.Name, GeneratedNames.AnonymousNamePrefix)) { continue; } var metadataName = reader.GetString(def.Name); short arity; var name = MetadataHelpers.InferTypeArityAndUnmangleMetadataName(metadataName, out arity); int index; if (GeneratedNames.TryParseAnonymousTypeTemplateName(name, out index)) { var builder = ArrayBuilder <AnonymousTypeKeyField> .GetInstance(); if (TryGetAnonymousTypeKey(reader, def, builder)) { var type = (NamedTypeSymbol)metadataDecoder.GetTypeOfToken(handle); var key = new AnonymousTypeKey(builder.ToImmutable()); var value = new AnonymousTypeValue(name, index, type); result.Add(key, value); } builder.Free(); } } return(result); }
public Visualizer(MetadataDecoder decoder) { _decoder = decoder; }
private static PENamedTypeSymbol GetType(PEModuleSymbol module, TypeDefinitionHandle typeHandle) { var metadataDecoder = new MetadataDecoder(module); return((PENamedTypeSymbol)metadataDecoder.GetTypeOfToken(typeHandle)); }
private SignatureData LoadSignature() { var moduleSymbol = _containingType.ContainingPEModule; SignatureHeader signatureHeader; BadImageFormatException mrEx; ParamInfo<TypeSymbol>[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(_handle, out signatureHeader, out mrEx); bool makeBad = (mrEx != null); // If method is not generic, let's assign empty list for type parameters if (!signatureHeader.IsGeneric && _lazyTypeParameters.IsDefault) { ImmutableInterlocked.InterlockedInitialize(ref _lazyTypeParameters, ImmutableArray<TypeParameterSymbol>.Empty); } int count = paramInfo.Length - 1; ImmutableArray<ParameterSymbol> @params; bool isBadParameter; if (count > 0) { var builder = ImmutableArray.CreateBuilder<ParameterSymbol>(count); for (int i = 0; i < count; i++) { builder.Add(PEParameterSymbol.Create(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter)); if (isBadParameter) { makeBad = true; } } @params = builder.ToImmutable(); } else { @params = ImmutableArray<ParameterSymbol>.Empty; } // Dynamify object type if necessary var returnType = paramInfo[0].Type.AsDynamicIfNoPia(_containingType); // Check for tuple type returnType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(returnType, paramInfo[0].Handle, moduleSymbol); paramInfo[0].Type = returnType; var returnParam = PEParameterSymbol.Create(moduleSymbol, this, 0, paramInfo[0], out isBadParameter); if (makeBad || isBadParameter) { InitializeUseSiteDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this)); } var signature = new SignatureData(signatureHeader, @params, returnParam); return InterlockedOperations.Initialize(ref _lazySignature, signature); }
internal PEEventSymbol( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, EventDefinitionHandle handle, PEMethodSymbol addMethod, PEMethodSymbol removeMethod, MultiDictionary<string, PEFieldSymbol> privateFieldNameToSymbols) { Debug.Assert((object)moduleSymbol != null); Debug.Assert((object)containingType != null); Debug.Assert(!handle.IsNil); Debug.Assert((object)addMethod != null); Debug.Assert((object)removeMethod != null); _addMethod = addMethod; _removeMethod = removeMethod; _handle = handle; _containingType = containingType; EventAttributes mdFlags = 0; EntityHandle eventType = default(EntityHandle); try { var module = moduleSymbol.Module; module.GetEventDefPropsOrThrow(handle, out _name, out mdFlags, out eventType); } catch (BadImageFormatException mrEx) { if ((object)_name == null) { _name = string.Empty; } _lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this); if (eventType.IsNil) { _eventType = new UnsupportedMetadataTypeSymbol(mrEx); } } TypeSymbol originalEventType = _eventType; if ((object)_eventType == null) { var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType); originalEventType = metadataDecoder.GetTypeOfToken(eventType); const int targetSymbolCustomModifierCount = 0; _eventType = DynamicTypeDecoder.TransformType(originalEventType, targetSymbolCustomModifierCount, handle, moduleSymbol); _eventType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(_eventType, handle, moduleSymbol); } // IsWindowsRuntimeEvent checks the signatures, so we just have to check the accessors. bool isWindowsRuntimeEvent = IsWindowsRuntimeEvent; bool callMethodsDirectly = isWindowsRuntimeEvent ? !DoModifiersMatch(_addMethod, _removeMethod) : !DoSignaturesMatch(moduleSymbol, originalEventType, _addMethod, _removeMethod); if (callMethodsDirectly) { _flags |= Flags.CallMethodsDirectly; } else { _addMethod.SetAssociatedEvent(this, MethodKind.EventAdd); _removeMethod.SetAssociatedEvent(this, MethodKind.EventRemove); PEFieldSymbol associatedField = GetAssociatedField(privateFieldNameToSymbols, isWindowsRuntimeEvent); if ((object)associatedField != null) { _associatedFieldOpt = associatedField; associatedField.SetAssociatedEvent(this); } } if ((mdFlags & EventAttributes.SpecialName) != 0) { _flags |= Flags.IsSpecialName; } if ((mdFlags & EventAttributes.RTSpecialName) != 0) { _flags |= Flags.IsRuntimeSpecialName; } }
public void HoistedAnonymousTypes_Complex() { var source0 = @" using System; class C { static void F() { var x1 = new[] { new { A = new { X = 1 } } }; var x2 = new[] { new { A = new { Y = 1 } } }; var y = new Func<int>(() => x1[0].A.X + x2[0].A.Y); } } "; var source1 = @" using System; class C { static void F() { var x1 = new[] { new { A = new { X = 1 } } }; var x2 = new[] { new { A = new { Z = 1 } } }; var y = new Func<int>(() => x1[0].A.X + x2[0].A.Z); } }"; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll); var peRef0 = compilation0.EmitToImageReference(); var peAssemblySymbol0 = (PEAssemblySymbol)CreateCompilation("", new[] { peRef0 }).GetReferencedAssemblySymbol(peRef0); var peModule0 = (PEModuleSymbol)peAssemblySymbol0.Modules[0]; var reader0 = peModule0.Module.MetadataReader; var decoder0 = new MetadataDecoder(peModule0); var anonymousTypeMap0 = PEDeltaAssemblyBuilder.GetAnonymousTypeMapFromMetadata(reader0, decoder0); Assert.Equal("<>f__AnonymousType0", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("A", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType1", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("X", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType2", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("Y", isKey: false, ignoreCase: false)))].Name); Assert.Equal(3, anonymousTypeMap0.Count); var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll); var testData = new CompilationTestData(); compilation1.EmitToArray(testData: testData); var peAssemblyBuilder = (PEAssemblyBuilder)testData.Module; var c = compilation1.GetMember <NamedTypeSymbol>("C"); var displayClass = peAssemblyBuilder.GetSynthesizedTypes(c).Single(); Assert.Equal("<>c__DisplayClass0_0", displayClass.Name); var emitContext = new EmitContext(peAssemblyBuilder, null, new DiagnosticBag(), metadataOnly: false, includePrivateMembers: true); var fields = displayClass.GetFields(emitContext).ToArray(); AssertEx.SetEqual(fields.Select(f => f.Name), new[] { "x1", "x2" }); var x1 = fields.Where(f => f.Name == "x1").Single(); var x2 = fields.Where(f => f.Name == "x2").Single(); var matcher = new CSharpSymbolMatcher(anonymousTypeMap0, compilation1.SourceAssembly, emitContext, peAssemblySymbol0); var mappedX1 = (Cci.IFieldDefinition)matcher.MapDefinition(x1); var mappedX2 = (Cci.IFieldDefinition)matcher.MapDefinition(x2); Assert.Equal("x1", mappedX1.Name); Assert.Null(mappedX2); }
internal PEAttributeData(PEModuleSymbol moduleSymbol, CustomAttributeHandle handle) { _decoder = new MetadataDecoder(moduleSymbol); _handle = handle; }
private ImmutableArray<TypeSymbol> GetDeclaredConstraintTypes() { PEMethodSymbol containingMethod = null; PENamedTypeSymbol containingType; if (_containingSymbol.Kind == SymbolKind.Method) { containingMethod = (PEMethodSymbol)_containingSymbol; containingType = (PENamedTypeSymbol)containingMethod.ContainingSymbol; } else { containingType = (PENamedTypeSymbol)_containingSymbol; } var moduleSymbol = containingType.ContainingPEModule; EntityHandle[] constraints; try { constraints = moduleSymbol.Module.GetGenericParamConstraintsOrThrow(_handle); } catch (BadImageFormatException) { constraints = null; Interlocked.CompareExchange(ref _lazyBoundsErrorInfo, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo); } if (constraints != null && constraints.Length > 0) { var symbolsBuilder = ArrayBuilder<TypeSymbol>.GetInstance(); MetadataDecoder tokenDecoder; if ((object)containingMethod != null) { tokenDecoder = new MetadataDecoder(moduleSymbol, containingMethod); } else { tokenDecoder = new MetadataDecoder(moduleSymbol, containingType); } foreach (var constraint in constraints) { TypeSymbol typeSymbol = tokenDecoder.GetTypeOfToken(constraint); // Drop 'System.Object' constraint type. if (typeSymbol.SpecialType == Microsoft.CodeAnalysis.SpecialType.System_Object) { continue; } // Drop 'System.ValueType' constraint type if the 'valuetype' constraint was also specified. if (((_flags & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) && (typeSymbol.SpecialType == Microsoft.CodeAnalysis.SpecialType.System_ValueType)) { continue; } symbolsBuilder.Add(typeSymbol); } return symbolsBuilder.ToImmutableAndFree(); } else { return ImmutableArray<TypeSymbol>.Empty; } }
public PEPropertySymbolWithCustomModifiers( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, PropertyDefinitionHandle handle, PEMethodSymbol getMethod, PEMethodSymbol setMethod, ParamInfo<TypeSymbol>[] propertyParams, MetadataDecoder metadataDecoder) : base (moduleSymbol, containingType, handle, getMethod, setMethod, propertyParams[0].CustomModifiers.NullToEmpty().Length + propertyParams[0].RefCustomModifiers.NullToEmpty().Length, propertyParams, metadataDecoder) { var returnInfo = propertyParams[0]; _typeCustomModifiers = CSharpCustomModifier.Convert(returnInfo.CustomModifiers); _refCustomModifiers = CSharpCustomModifier.Convert(returnInfo.RefCustomModifiers); }
private void LoadSignature() { var moduleSymbol = this.containingType.ContainingPEModule; byte callingConvention; BadImageFormatException mrEx; MetadataDecoder.ParamInfo[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(this.handle, out callingConvention, out mrEx); bool makeBad = (mrEx != null); // If method is not generic, let's assign empty list for type parameters if (!SignatureHeader.IsGeneric(callingConvention) && lazyTypeParameters.IsDefault) { ImmutableInterlocked.InterlockedCompareExchange(ref lazyTypeParameters, ImmutableArray<TypeParameterSymbol>.Empty, default(ImmutableArray<TypeParameterSymbol>)); } int count = paramInfo.Length - 1; ImmutableArray<ParameterSymbol> @params; bool isBadParameter; if (count > 0) { ParameterSymbol[] parameterCreation = new ParameterSymbol[count]; for (int i = 0; i < count; i++) { parameterCreation[i] = new PEParameterSymbol(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter); if (isBadParameter) { makeBad = true; } } @params = parameterCreation.AsImmutableOrNull(); } else { @params = ImmutableArray<ParameterSymbol>.Empty; } // paramInfo[0] contains information about return "parameter" Debug.Assert(!paramInfo[0].IsByRef); // Dynamify object type if necessary paramInfo[0].Type = paramInfo[0].Type.AsDynamicIfNoPia(this.containingType); var returnParam = new PEParameterSymbol(moduleSymbol, this, 0, paramInfo[0], out isBadParameter); if (makeBad || isBadParameter) { var old = Interlocked.CompareExchange(ref lazyUseSiteDiagnostic, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo); Debug.Assert((object)old == (object)CSDiagnosticInfo.EmptyErrorInfo || ((object)old != null && old.Code == (int)ErrorCode.ERR_BindToBogus && old.Arguments.Length == 1 && old.Arguments[0] == (object)this)); } var signature = new SignatureData(callingConvention, @params, returnParam); Interlocked.CompareExchange(ref lazySignature, signature, null); }
/// <summary> /// </summary> /// <param name="localInfo"> /// </param> /// <param name="index"> /// </param> internal MetadataLocalVariableAdapter(MetadataDecoder<TypeSymbol, MethodSymbol, FieldSymbol, AssemblySymbol, Symbol>.LocalInfo localInfo, int index) { Debug.Assert(localInfo.Type.TypeKind != TypeKind.Error); this.localInfo = localInfo; this.LocalIndex = index; }
private static LocalSlotConstraints GetConstraints(MetadataDecoder.LocalInfo info) { return (info.IsPinned ? LocalSlotConstraints.Pinned : LocalSlotConstraints.None) | (info.IsByRef ? LocalSlotConstraints.ByRef : LocalSlotConstraints.None); }
public void HoistedAnonymousTypes_Complex() { var source0 = @" using System; class C { static void F() { var x1 = new[] { new { A = new { X = 1 } } }; var x2 = new[] { new { A = new { Y = 1 } } }; var y = new Func<int>(() => x1[0].A.X + x2[0].A.Y); } } "; var source1 = @" using System; class C { static void F() { var x1 = new[] { new { A = new { X = 1 } } }; var x2 = new[] { new { A = new { Z = 1 } } }; var y = new Func<int>(() => x1[0].A.X + x2[0].A.Z); } }"; var compilation0 = CreateCompilationWithMscorlib(source0, options: TestOptions.DebugDll); var peRef0 = compilation0.EmitToImageReference(); var peAssemblySymbol0 = (PEAssemblySymbol)CreateCompilationWithMscorlib("", new[] { peRef0 }).GetReferencedAssemblySymbol(peRef0); var peModule0 = (PEModuleSymbol)peAssemblySymbol0.Modules[0]; var reader0 = peModule0.Module.MetadataReader; var decoder0 = new MetadataDecoder(peModule0); var anonymousTypeMap0 = PEDeltaAssemblyBuilder.GetAnonymousTypeMapFromMetadata(reader0, decoder0); Assert.Equal("<>f__AnonymousType0", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("A", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType1", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("X", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType2", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("Y", isKey: false, ignoreCase: false)))].Name); Assert.Equal(3, anonymousTypeMap0.Count); var compilation1 = CreateCompilationWithMscorlib(source1, options: TestOptions.DebugDll); var testData = new CompilationTestData(); compilation1.EmitToArray(testData: testData); var peAssemblyBuilder = (PEAssemblyBuilder)testData.Module; var c = compilation1.GetMember<NamedTypeSymbol>("C"); var displayClass = peAssemblyBuilder.GetSynthesizedTypes(c).Single(); Assert.Equal("<>c__DisplayClass0_0", displayClass.Name); var emitContext = new EmitContext(peAssemblyBuilder, null, new DiagnosticBag()); var fields = displayClass.GetFields(emitContext).ToArray(); var x1 = fields[0]; var x2 = fields[1]; Assert.Equal("x1", x1.Name); Assert.Equal("x2", x2.Name); var matcher = new CSharpSymbolMatcher(anonymousTypeMap0, compilation1.SourceAssembly, emitContext, peAssemblySymbol0); var mappedX1 = (Cci.IFieldDefinition)matcher.MapDefinition(x1); var mappedX2 = (Cci.IFieldDefinition)matcher.MapDefinition(x2); Assert.Equal("x1", mappedX1.Name); Assert.Null(mappedX2); }
internal PEPropertySymbol( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, PropertyHandle handle, PEMethodSymbol getMethod, PEMethodSymbol setMethod) { Debug.Assert((object)moduleSymbol != null); Debug.Assert((object)containingType != null); Debug.Assert(!handle.IsNil); this.containingType = containingType; var module = moduleSymbol.Module; PropertyAttributes mdFlags = 0; BadImageFormatException mrEx = null; try { module.GetPropertyDefPropsOrThrow(handle, out this.name, out mdFlags); } catch (BadImageFormatException e) { mrEx = e; if ((object)this.name == null) { this.name = string.Empty; } } this.getMethod = getMethod; this.setMethod = setMethod; this.handle = handle; var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType); byte callingConvention; BadImageFormatException propEx; var propertyParams = metadataDecoder.GetSignatureForProperty(handle, out callingConvention, out propEx); Debug.Assert(propertyParams.Length > 0); byte unusedCallingConvention; BadImageFormatException getEx = null; var getMethodParams = (object)getMethod == null ? null : metadataDecoder.GetSignatureForMethod(getMethod.Handle, out unusedCallingConvention, out getEx); BadImageFormatException setEx = null; var setMethodParams = (object)setMethod == null ? null : metadataDecoder.GetSignatureForMethod(setMethod.Handle, out unusedCallingConvention, out setEx); // NOTE: property parameter names are not recorded in metadata, so we have to // use the parameter names from one of the indexers. // NB: prefer setter names to getter names if both are present. bool isBad; this.parameters = GetParameters(moduleSymbol, this, propertyParams, setMethodParams ?? getMethodParams, out isBad); if (propEx != null || getEx != null || setEx != null || mrEx != null || isBad) { lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this); } this.typeCustomModifiers = CSharpCustomModifier.Convert(propertyParams[0].CustomModifiers); // CONSIDER: Can we make parameter type computation lazy? TypeSymbol originalPropertyType = propertyParams[0].Type; this.propertyType = DynamicTypeDecoder.TransformType(originalPropertyType, typeCustomModifiers.Length, handle, moduleSymbol); // Dynamify object type if necessary this.propertyType = this.propertyType.AsDynamicIfNoPia(this.containingType); // A property is bogus and must be accessed by calling its accessors directly if the // accessor signatures do not agree, both with each other and with the property, // or if it has parameters and is not an indexer or indexed property. bool callMethodsDirectly = !DoSignaturesMatch(module, metadataDecoder, propertyParams, this.getMethod, getMethodParams, this.setMethod, setMethodParams) || MustCallMethodsDirectlyCore(); if (!callMethodsDirectly) { if ((object)this.getMethod != null) { this.getMethod.SetAssociatedProperty(this, MethodKind.PropertyGet); } if ((object)this.setMethod != null) { this.setMethod.SetAssociatedProperty(this, MethodKind.PropertySet); } } if (callMethodsDirectly) { flags |= Flags.CallMethodsDirectly; } if ((mdFlags & PropertyAttributes.SpecialName) != 0) { flags |= Flags.IsSpecialName; } if ((mdFlags & PropertyAttributes.RTSpecialName) != 0) { flags |= Flags.IsRuntimeSpecialName; } }
internal PEEventSymbol( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, EventHandle handle, PEMethodSymbol addMethod, PEMethodSymbol removeMethod) { Debug.Assert((object)moduleSymbol != null); Debug.Assert((object)containingType != null); Debug.Assert(!handle.IsNil); Debug.Assert((object)addMethod != null); Debug.Assert((object)removeMethod != null); this.addMethod = addMethod; this.removeMethod = removeMethod; this.handle = handle; this.containingType = containingType; EventAttributes mdFlags = 0; Handle eventType = default(Handle); try { var module = moduleSymbol.Module; module.GetEventDefPropsOrThrow(handle, out this.name, out mdFlags, out eventType); } catch (BadImageFormatException mrEx) { if ((object)this.name == null) { this.name = string.Empty; } lazyUseSiteDiagnostic = new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this); if (eventType.IsNil) { this.eventType = new UnsupportedMetadataTypeSymbol(mrEx); } } if ((object)this.eventType == null) { var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType); this.eventType = metadataDecoder.GetTypeOfToken(eventType); } // IsWindowsRuntimeEvent checks the signatures, so we just have to check the accessors. bool callMethodsDirectly = IsWindowsRuntimeEvent ? !DoModifiersMatch(this.addMethod, this.removeMethod) : !DoSignaturesMatch(moduleSymbol, this.eventType, this.addMethod, this.removeMethod); if (callMethodsDirectly) { flags |= Flags.CallMethodsDirectly; } else { this.addMethod.SetAssociatedEvent(this, MethodKind.EventAdd); this.removeMethod.SetAssociatedEvent(this, MethodKind.EventRemove); } if ((mdFlags & EventAttributes.SpecialName) != 0) { flags |= Flags.IsSpecialName; } if ((mdFlags & EventAttributes.RTSpecialName) != 0) { flags |= Flags.IsRuntimeSpecialName; } }
// internal for testing internal static IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> GetAnonymousTypeMapFromMetadata(MetadataReader reader, MetadataDecoder metadataDecoder) { // In general, the anonymous type name is "<{module-id}>f__AnonymousType{index}#{submission-index}", // but EnC is not supported for modules nor submissions. Hence we only look for type names with no module id and no submission index. const string AnonymousNameWithoutModulePrefix = "<>f__AnonymousType"; var result = new Dictionary <AnonymousTypeKey, AnonymousTypeValue>(); foreach (var handle in reader.TypeDefinitions) { var def = reader.GetTypeDefinition(handle); if (!def.Namespace.IsNil) { continue; } if (!reader.StringComparer.StartsWith(def.Name, AnonymousNameWithoutModulePrefix)) { continue; } var metadataName = reader.GetString(def.Name); var name = MetadataHelpers.InferTypeArityAndUnmangleMetadataName(metadataName, out _); if (name.StartsWith(AnonymousNameWithoutModulePrefix, StringComparison.Ordinal) && int.TryParse(name.Substring(AnonymousNameWithoutModulePrefix.Length), NumberStyles.None, CultureInfo.InvariantCulture, out int index)) { var builder = ArrayBuilder <AnonymousTypeKeyField> .GetInstance(); if (TryGetAnonymousTypeKey(reader, def, builder)) { var type = (NamedTypeSymbol)metadataDecoder.GetTypeOfToken(handle); var key = new AnonymousTypeKey(builder.ToImmutable()); var value = new AnonymousTypeValue(name, index, type.GetCciAdapter()); result.Add(key, value); } builder.Free(); } } return(result); }
private IEnumerable<ILocalVariable> GetLocalVariables() { var localInfo = default(ImmutableArray<MetadataDecoder<TypeSymbol, MethodSymbol, FieldSymbol, AssemblySymbol, Symbol>.LocalInfo>); try { PEModuleSymbol peModuleSymbol; PEMethodSymbol peMethodSymbol; this.GetPEMethodSymbol(out peModuleSymbol, out peMethodSymbol); if (peMethodSymbol != null) { var methodBody = this.GetMethodBodyBlock(peModuleSymbol, peMethodSymbol); if (methodBody != null && !methodBody.LocalSignature.IsNil) { var module = peModuleSymbol.Module; var signatureHandle = module.MetadataReader.GetLocalSignature(methodBody.LocalSignature); var signatureReader = module.GetMemoryReaderOrThrow(signatureHandle); localInfo = new MetadataDecoder(peModuleSymbol, peMethodSymbol).DecodeLocalSignatureOrThrow(ref signatureReader); var index = 0; return localInfo.Select(li => new MetadataLocalVariableAdapter(li, index++, this.GenericContext)).ToArray(); } } } catch (UnsupportedSignatureContent) { } catch (BadImageFormatException) { } return new ILocalVariable[0]; }
private bool IsFixedBuffer(out int fixedSize, out TypeSymbol fixedElementType) { fixedSize = 0; fixedElementType = null; string elementTypeName; int bufferSize; PEModuleSymbol containingPEModule = this.ContainingPEModule; if (containingPEModule.Module.HasFixedBufferAttribute(_handle, out elementTypeName, out bufferSize)) { var decoder = new MetadataDecoder(containingPEModule); var elementType = decoder.GetTypeSymbolForSerializedType(elementTypeName); if (elementType.FixedBufferElementSizeInBytes() != 0) { fixedSize = bufferSize; fixedElementType = elementType; return true; } } return false; }
private static bool DoSignaturesMatch( PEModule module, MetadataDecoder metadataDecoder, MetadataDecoder.ParamInfo[] propertyParams, PEMethodSymbol getMethod, MetadataDecoder.ParamInfo[] getMethodParams, PEMethodSymbol setMethod, MetadataDecoder.ParamInfo[] setMethodParams) { Debug.Assert((getMethodParams == null) == ((object)getMethod == null)); Debug.Assert((setMethodParams == null) == ((object)setMethod == null)); bool hasGetMethod = getMethodParams != null; bool hasSetMethod = setMethodParams != null; if (hasGetMethod && !metadataDecoder.DoPropertySignaturesMatch(propertyParams, getMethodParams, comparingToSetter: false, compareParamByRef: true, compareReturnType: true)) { return false; } if (hasSetMethod && !metadataDecoder.DoPropertySignaturesMatch(propertyParams, setMethodParams, comparingToSetter: true, compareParamByRef: true, compareReturnType: true)) { return false; } if (hasGetMethod && hasSetMethod) { var lastPropertyParamIndex = propertyParams.Length - 1; var getHandle = getMethodParams[lastPropertyParamIndex].Handle; var setHandle = setMethodParams[lastPropertyParamIndex].Handle; var getterHasParamArray = !getHandle.IsNil && module.HasParamsAttribute(getHandle); var setterHasParamArray = !setHandle.IsNil && module.HasParamsAttribute(setHandle); if (getterHasParamArray != setterHasParamArray) { return false; } if ((getMethod.IsExtern != setMethod.IsExtern) || // (getMethod.IsAbstract != setMethod.IsAbstract) || // NOTE: Dev10 accepts one abstract accessor (getMethod.IsSealed != setMethod.IsSealed) || (getMethod.IsOverride != setMethod.IsOverride) || (getMethod.IsStatic != setMethod.IsStatic)) { return false; } } return true; }
private ImmutableArray<TypeSymbol> GetDeclaredConstraintTypes() { PEMethodSymbol containingMethod = null; PENamedTypeSymbol containingType; if (_containingSymbol.Kind == SymbolKind.Method) { containingMethod = (PEMethodSymbol)_containingSymbol; containingType = (PENamedTypeSymbol)containingMethod.ContainingSymbol; } else { containingType = (PENamedTypeSymbol)_containingSymbol; } var moduleSymbol = containingType.ContainingPEModule; var metadataReader = moduleSymbol.Module.MetadataReader; GenericParameterConstraintHandleCollection constraints; try { constraints = metadataReader.GetGenericParameter(_handle).GetConstraints(); } catch (BadImageFormatException) { constraints = default(GenericParameterConstraintHandleCollection); Interlocked.CompareExchange(ref _lazyBoundsErrorInfo, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo); } if (constraints.Count > 0) { var symbolsBuilder = ArrayBuilder<TypeSymbol>.GetInstance(); MetadataDecoder tokenDecoder; if ((object)containingMethod != null) { tokenDecoder = new MetadataDecoder(moduleSymbol, containingMethod); } else { tokenDecoder = new MetadataDecoder(moduleSymbol, containingType); } foreach (var constraintHandle in constraints) { var constraint = metadataReader.GetGenericParameterConstraint(constraintHandle); var constraintTypeHandle = constraint.Type; TypeSymbol typeSymbol = tokenDecoder.GetTypeOfToken(constraintTypeHandle); // Drop 'System.Object' constraint type. if (typeSymbol.SpecialType == SpecialType.System_Object) { continue; } // Drop 'System.ValueType' constraint type if the 'valuetype' constraint was also specified. if (((_flags & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) && (typeSymbol.SpecialType == SpecialType.System_ValueType)) { continue; } typeSymbol = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeSymbol, constraintHandle, moduleSymbol); symbolsBuilder.Add(typeSymbol); } return symbolsBuilder.ToImmutableAndFree(); } else { return ImmutableArray<TypeSymbol>.Empty; } }
/// <summary> /// </summary> /// <param name="fullName"> /// </param> /// <param name="genericContext"> /// </param> /// <returns> /// </returns> /// <exception cref="KeyNotFoundException"> /// </exception> public IType ResolveType(string fullName, IGenericContext genericContext) { var peModuleSymbol = this.moduleDef as PEModuleSymbol; var typeSymbol = peModuleSymbol.GetMetadataDecoder(genericContext).GetTypeSymbolForSerializedType(fullName); if (typeSymbol.TypeKind == TypeKind.Error) { // try to find it in CoreLib typeSymbol = new MetadataDecoder(peModuleSymbol.ContainingAssembly.CorLibrary.Modules[0] as PEModuleSymbol).GetTypeSymbolForSerializedType(fullName); } if (typeSymbol != null && typeSymbol.TypeKind != TypeKind.Error) { if (genericContext == null) { return typeSymbol.OriginalDefinition.ToAdapter(); } return typeSymbol.ToAdapter(); } throw new KeyNotFoundException(); }
// internal for testing internal static IReadOnlyDictionary<AnonymousTypeKey, AnonymousTypeValue> GetAnonymousTypeMapFromMetadata(MetadataReader reader, MetadataDecoder metadataDecoder) { var result = new Dictionary<AnonymousTypeKey, AnonymousTypeValue>(); foreach (var handle in reader.TypeDefinitions) { var def = reader.GetTypeDefinition(handle); if (!def.Namespace.IsNil) { continue; } if (!reader.StringComparer.StartsWith(def.Name, GeneratedNames.AnonymousNamePrefix)) { continue; } var metadataName = reader.GetString(def.Name); short arity; var name = MetadataHelpers.InferTypeArityAndUnmangleMetadataName(metadataName, out arity); int index; if (GeneratedNames.TryParseAnonymousTypeTemplateName(name, out index)) { var builder = ArrayBuilder<AnonymousTypeKeyField>.GetInstance(); if (TryGetAnonymousTypeKey(reader, def, builder)) { var type = (NamedTypeSymbol)metadataDecoder.GetTypeOfToken(handle); var key = new AnonymousTypeKey(builder.ToImmutable()); var value = new AnonymousTypeValue(name, index, type); result.Add(key, value); } builder.Free(); } } return result; }
private static bool DoesSignatureMatch( PEModuleSymbol moduleSymbol, TypeSymbol eventType, PEMethodSymbol method) { // CONSIDER: It would be nice if we could reuse this signature information in the PEMethodSymbol. var metadataDecoder = new MetadataDecoder(moduleSymbol, method); SignatureHeader signatureHeader; BadImageFormatException mrEx; var methodParams = metadataDecoder.GetSignatureForMethod(method.Handle, out signatureHeader, out mrEx, setParamHandles: false); if (mrEx != null) { return false; } return metadataDecoder.DoesSignatureMatchEvent(eventType, methodParams); }
private EmitBaseline.MetadataSymbols GetOrCreateMetadataSymbols(EmitBaseline initialBaseline, CSharpCompilation compilation) { if (initialBaseline.LazyMetadataSymbols != null) { return initialBaseline.LazyMetadataSymbols; } var originalMetadata = initialBaseline.OriginalMetadata; // The purpose of this compilation is to provide PE symbols for original metadata. // We need to transfer the references from the current source compilation but don't need its syntax trees. var metadataCompilation = compilation.RemoveAllSyntaxTrees(); var metadataAssembly = metadataCompilation.GetBoundReferenceManager().CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata.Create(originalMetadata), MetadataImportOptions.All); var metadataDecoder = new MetadataDecoder(metadataAssembly.PrimaryModule); var metadataAnonymousTypes = GetAnonymousTypeMapFromMetadata(originalMetadata.MetadataReader, metadataDecoder); var metadataSymbols = new EmitBaseline.MetadataSymbols(metadataAnonymousTypes, metadataDecoder); return InterlockedOperations.Initialize(ref initialBaseline.LazyMetadataSymbols, metadataSymbols); }
public void Bug654522() { var compilation = CreateCompilationWithMscorlibAndSystemCore("public interface I<W> where W : struct {}").VerifyDiagnostics(); Action<ModuleSymbol> metadataValidator = delegate(ModuleSymbol module) { var metadata = ((PEModuleSymbol)module).Module; var typeI = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("I").Single(); Assert.Equal(1, typeI.TypeParameters.Length); var tp = (PETypeParameterSymbol)typeI.TypeParameters[0]; string name; GenericParameterAttributes flags; metadata.GetGenericParamPropsOrThrow(tp.Handle, out name, out flags); Assert.Equal(GenericParameterAttributes.DefaultConstructorConstraint, flags & GenericParameterAttributes.DefaultConstructorConstraint); var constraints = metadata.GetGenericParamConstraintsOrThrow(tp.Handle); Assert.Equal(1, constraints.Length); var tokenDecoder = new MetadataDecoder((PEModuleSymbol)module, typeI); TypeSymbol typeSymbol = tokenDecoder.GetTypeOfToken(constraints[0]); Assert.Equal(SpecialType.System_ValueType, typeSymbol.SpecialType); }; CompileAndVerify(compilation, symbolValidator: metadataValidator); }
public void HoistedAnonymousTypes() { var source0 = @" using System; class C { static void F() { var x1 = new { A = 1 }; var x2 = new { B = 1 }; var y = new Func<int>(() => x1.A + x2.B); } } "; var source1 = @" using System; class C { static void F() { var x1 = new { A = 1 }; var x2 = new { b = 1 }; var y = new Func<int>(() => x1.A + x2.b); } }"; var compilation0 = CreateCompilationWithMscorlib(source0, options: TestOptions.DebugDll); var peRef0 = compilation0.EmitToImageReference(); var peAssemblySymbol0 = (PEAssemblySymbol)CreateCompilationWithMscorlib("", new[] { peRef0 }).GetReferencedAssemblySymbol(peRef0); var peModule0 = (PEModuleSymbol)peAssemblySymbol0.Modules[0]; var reader0 = peModule0.Module.MetadataReader; var decoder0 = new MetadataDecoder(peModule0); var anonymousTypeMap0 = PEDeltaAssemblyBuilder.GetAnonymousTypeMapFromMetadata(reader0, decoder0); Assert.Equal("<>f__AnonymousType0", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("A", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType1", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("B", isKey: false, ignoreCase: false)))].Name); Assert.Equal(2, anonymousTypeMap0.Count); var compilation1 = CreateCompilationWithMscorlib(source1, options: TestOptions.DebugDll); var testData = new CompilationTestData(); compilation1.EmitToArray(testData: testData); var peAssemblyBuilder = (PEAssemblyBuilder)testData.Module; var c = compilation1.GetMember <NamedTypeSymbol>("C"); var displayClass = peAssemblyBuilder.GetSynthesizedTypes(c).Single(); Assert.Equal("<>c__DisplayClass0_0", displayClass.Name); var emitContext = new EmitContext(peAssemblyBuilder, null, new DiagnosticBag()); var fields = displayClass.GetFields(emitContext).ToArray(); var x1 = fields[0]; var x2 = fields[1]; Assert.Equal("x1", x1.Name); Assert.Equal("x2", x2.Name); var matcher = new CSharpSymbolMatcher(anonymousTypeMap0, compilation1.SourceAssembly, emitContext, peAssemblySymbol0); var mappedX1 = (Cci.IFieldDefinition)matcher.MapDefinition(x1); var mappedX2 = (Cci.IFieldDefinition)matcher.MapDefinition(x2); Assert.Equal("x1", mappedX1.Name); Assert.Null(mappedX2); }