public void UnifyStructural_MissingProperty_Fail() { var unifier = new TypeUnifier(); var typeToSlim = new TypeToTypeSlimConverter(); var rtc = new RuntimeCompiler(); var typeBuilder1 = rtc.GetNewRecordTypeBuilder(); var typeBuilder2 = rtc.GetNewRecordTypeBuilder(); rtc.DefineRecordType( typeBuilder1, (new Dictionary <string, Type> { { "foo", typeof(int) } }).AsEnumerable(), true ); rtc.DefineRecordType( typeBuilder2, (new Dictionary <string, Type> { { "bar", typeof(double) } }).AsEnumerable(), true ); var structuralType1 = typeBuilder1.CreateType(); var structuralType2 = typeBuilder2.CreateType(); var slimStructuralType = typeToSlim.Visit(structuralType2); unifier.Unify(structuralType1, slimStructuralType); }
public void StructuralTypeEqualityComparer_ManOrBoy_Failure() { var rtc = new RuntimeCompiler(); var rt1 = rtc.GetNewRecordTypeBuilder(); var rt2 = rtc.GetNewRecordTypeBuilder(); var at1 = rtc.GetNewAnonymousTypeBuilder(); var at2 = rtc.GetNewAnonymousTypeBuilder(); rtc.DefineRecordType( rt1, new Dictionary <string, Type> { { "Self", rt1 }, { "Copy", rt2 }, { "Other", typeof(int) } }, true); rtc.DefineRecordType( rt2, new Dictionary <string, Type> { { "Self", rt2 }, { "Copy", rt1 }, { "Other", typeof(string) } }, true); rtc.DefineAnonymousType( at1, new Dictionary <string, Type> { { "Self", at1 }, { "Copy", at2 }, { "Other", typeof(int) } }, null); rtc.DefineAnonymousType( at2, new Dictionary <string, Type> { { "Self", at2 }, { "Copy", at1 }, { "Other", typeof(string) } }, null); rt1.CreateType(); rt2.CreateType(); at1.CreateType(); at2.CreateType(); var eq = new StructuralTypeEqualityComparer(); Assert.IsFalse(eq.Equals(rt1, rt2)); Assert.IsFalse(eq.Equals(at1, at2)); }
public void DefineRecordType_ArgumentChecks() { var rtc = new RuntimeCompiler(); var rtb = rtc.GetNewRecordTypeBuilder(); AssertEx.ThrowsException <ArgumentNullException>(() => rtc.DefineRecordType(recordTypeBuilder: null, Array.Empty <KeyValuePair <string, Type> >(), valueEquality: true), ex => Assert.AreEqual("recordTypeBuilder", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => rtc.DefineRecordType(rtb, properties: (KeyValuePair <string, Type>[])null, valueEquality: true), ex => Assert.AreEqual("properties", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => rtc.DefineRecordType(recordTypeBuilder: null, Array.Empty <StructuralFieldDeclaration>(), valueEquality: true), ex => Assert.AreEqual("recordTypeBuilder", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => rtc.DefineRecordType(rtb, properties: (StructuralFieldDeclaration[])null, valueEquality: true), ex => Assert.AreEqual("properties", ex.ParamName)); }
public void UnifyStructural_DifferentPropertyTypes_Pass() { var unifier = new TypeUnifier(); var typeToSlim = new TypeToTypeSlimConverter(); var rtc = new RuntimeCompiler(); var typeBuilder = rtc.GetNewRecordTypeBuilder(); rtc.DefineRecordType( typeBuilder, (new Dictionary <string, Type> { { "foo", typeof(int) } }).AsEnumerable(), true ); var structuralType = typeBuilder.CreateType(); var slimStructuralType = typeToSlim.Visit(structuralType); Assert.IsTrue(unifier.Unify(structuralType, slimStructuralType)); Assert.AreEqual(1, unifier.Entries.Count); Assert.IsTrue(unifier.Entries.ContainsKey(slimStructuralType)); Assert.AreEqual(unifier.Entries[slimStructuralType], structuralType); Assert.IsTrue(slimStructuralType is StructuralTypeSlim); }
public void RecordType_TypeBuilder_StructuralFields() { foreach (var eq in new[] { true, false }) { RecordType_Impl(() => { var rtc = new RuntimeCompiler(); var rtb = rtc.GetNewRecordTypeBuilder(); rtc.DefineRecordType(rtb, new[] { new StructuralFieldDeclaration("Name", typeof(string)), new StructuralFieldDeclaration("Age", typeof(int)), }, eq); return(rtb.CreateType()); }, eq); } }
public void RecordType_TypeBuilder() { foreach (var eq in new[] { true, false }) { RecordType_Impl(() => { var rtc = new RuntimeCompiler(); var rtb = rtc.GetNewRecordTypeBuilder(); rtc.DefineRecordType(rtb, new[] { new KeyValuePair <string, Type>("Name", typeof(string)), new KeyValuePair <string, Type>("Age", typeof(int)), }, eq); return(rtb.CreateType()); }, eq); } }
public void TypeSlim_RecursiveRecordType_ToString() { var rtc = new RuntimeCompiler(); var builder = rtc.GetNewRecordTypeBuilder(); rtc.DefineRecordType( builder, new Dictionary <string, Type> { { "self", builder } }.AsEnumerable(), true ); var type = builder.CreateType(); var slimifier = new TypeToTypeSlimConverter(); var slim = slimifier.Visit(type); Assert.AreEqual("{self : {1}} as {1}", slim.ToString()); }
public void RecordType_Visibility() { var props = new[] { new KeyValuePair <string, Type>("bar", typeof(Bar)) }; var props2 = new[] { new StructuralFieldDeclaration("bar", typeof(string), new List <CustomAttributeDeclaration> { new CustomAttributeDeclaration(typeof(BarAttribute), new List <object>().AsReadOnly()) }.AsReadOnly()) }; var props3 = new[] { new StructuralFieldDeclaration("bar", typeof(Bar)) }; Assert.ThrowsException <InvalidOperationException>(() => RuntimeCompiler.CreateRecordType(props, valueEquality: true)); Assert.ThrowsException <InvalidOperationException>(() => { var rtc = new RuntimeCompiler(); var atb = rtc.GetNewRecordTypeBuilder(); rtc.DefineRecordType(atb, props, valueEquality: true); }); Assert.ThrowsException <InvalidOperationException>(() => RuntimeCompiler.CreateRecordType(props2, valueEquality: true)); Assert.ThrowsException <InvalidOperationException>(() => { var rtc = new RuntimeCompiler(); var atb = rtc.GetNewRecordTypeBuilder(); rtc.DefineRecordType(atb, props2, valueEquality: true); }); Assert.ThrowsException <InvalidOperationException>(() => RuntimeCompiler.CreateRecordType(props3, valueEquality: true)); Assert.ThrowsException <InvalidOperationException>(() => { var rtc = new RuntimeCompiler(); var atb = rtc.GetNewRecordTypeBuilder(); rtc.DefineRecordType(atb, props3, valueEquality: true); }); }
public void StructuralTypeEqualityComparer_ManOrBoy1_Success() { var rtc = new RuntimeCompiler(); var rt1 = rtc.GetNewRecordTypeBuilder(); var rt2 = rtc.GetNewRecordTypeBuilder(); var at1 = rtc.GetNewAnonymousTypeBuilder(); var at2 = rtc.GetNewAnonymousTypeBuilder(); rtc.DefineRecordType( rt1, new Dictionary <string, Type> { { "Self", rt1 }, { "Copy", rt2 }, { "Other", at1 } }, true); rtc.DefineRecordType( rt2, new Dictionary <string, Type> { { "Self", rt2 }, { "Copy", rt1 }, { "Other", at2 } }, true); rtc.DefineAnonymousType( at1, new Dictionary <string, Type> { { "Self", at1 }, { "Copy", at2 }, { "Other", rt1 } }, null); rtc.DefineAnonymousType( at2, new Dictionary <string, Type> { { "Self", at2 }, { "Copy", at1 }, { "Other", rt2 } }, null); var rt1c = rt1.CreateType(); var rt2c = rt2.CreateType(); var at1c = at1.CreateType(); var at2c = at2.CreateType(); var eq = new StructuralTypeEqualityComparer(); var orig = new TypeEqualityComparer(); Assert.IsFalse(orig.Equals(rt1c, rt2c)); Assert.IsTrue(eq.Equals(rt1c, rt2c)); Assert.IsFalse(orig.Equals(at1c, at2c)); Assert.IsTrue(eq.Equals(at1c, at2c)); }
/// <summary> /// Define a type using a runtime compiler instance, a type builder, and a set of properties. /// </summary> /// <param name="rtc">The runtime compiler.</param> /// <param name="builder">The type builder to use for the type.</param> /// <param name="properties">The properties to add to the type.</param> protected override void DefineType(RuntimeCompiler rtc, TypeBuilder builder, IEnumerable <KeyValuePair <string, Type> > properties) => rtc.DefineRecordType(builder, properties, valueEquality: true);