public System.Type NativeFromTupleType(TupleType tupleType)
{
var typeBuilder = _module.DefineType("Tuple" + tupleType.GetHashCode(), TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.SequentialLayout | TypeAttributes.Serializable, typeof(ValueType));
var fieldsByID = new Dictionary<Name, FieldInfo>();
// Add attributes
foreach (var attribute in tupleType.Attributes)
{
var field = typeBuilder.DefineField(attribute.Key.ToString(), attribute.Value.GetNative(this), FieldAttributes.Public);
fieldsByID.Add(attribute.Key, field);
}
// Add references
foreach (var reference in tupleType.References)
{
var cab =
new CustomAttributeBuilder
(
typeof(TupleReferenceAttribute).GetConstructor(new System.Type[] { typeof(string), typeof(string[]), typeof(string), typeof(string[]) }),
new object[]
{
reference.Key.ToString(),
(from san in reference.Value.SourceAttributeNames select san.ToString()).ToArray(),
reference.Value.Target.ToString(),
(from tan in reference.Value.TargetAttributeNames select tan.ToString()).ToArray(),
}
);
typeBuilder.SetCustomAttribute(cab);
}
// Add keys
foreach (var key in tupleType.Keys)
{
var cab =
new CustomAttributeBuilder
(
typeof(TupleKeyAttribute).GetConstructor(new System.Type[] { typeof(string[]) }),
new object[] { (from an in key.AttributeNames select an.ToString()).ToArray() }
);
typeBuilder.SetCustomAttribute(cab);
}
// Add tuple attribute
var attributeBuilder =
new CustomAttributeBuilder
(
typeof(TupleAttribute).GetConstructor(new System.Type[] { }),
new object[] { }
);
typeBuilder.SetCustomAttribute(attributeBuilder);
// Add comparison and hash methods based on key(s)
EmitTupleGetHashCode(tupleType, typeBuilder, fieldsByID);
var equalityMethod = EmitTupleEquality(tupleType, typeBuilder, fieldsByID);
EmitTupleInequality(typeBuilder, equalityMethod);
EmitTupleEquals(typeBuilder, equalityMethod);
// Create the type
return typeBuilder.CreateType();
}