void GenerateClass(JObject[] examples, JsonType type)
{
var jsonFields = new Dictionary<string, JsonType>();
var fieldExamples = new Dictionary<string, IList<object>>();
var first = true;
foreach (var obj in examples)
{
foreach (var prop in obj.Properties())
{
JsonType fieldType;
var currentType = new JsonType(this, prop.Value);
var propName = prop.Name;
if (jsonFields.TryGetValue(propName, out fieldType))
{
var commonType = fieldType.GetCommonType(currentType);
jsonFields[propName] = commonType;
}
else
{
var commonType = currentType;
commonType = first ? commonType.MaybeMakeNullable (this) : commonType.GetCommonType (JsonType.GetNull (this));
jsonFields.Add(propName, commonType);
fieldExamples[propName] = new List<object>();
}
var fe = fieldExamples[propName];
var val = prop.Value;
if (val.Type == JTokenType.Null || val.Type == JTokenType.Undefined)
{
if (!fe.Contains(null))
{
fe.Insert(0, null);
}
}
else
{
var v = val.Type == JTokenType.Array || val.Type == JTokenType.Object ? val : val.Value<object>();
if (!fe.Any (v.Equals))
fe.Add(v);
}
}
first = false;
}
if (UseNestedClasses)
{
foreach (var field in jsonFields)
{
Names.Add(field.Key.ToLower());
}
}
foreach (var field in jsonFields)
{
var fieldType = field.Value;
if (fieldType.Type == JsonTypeEnum.Object)
{
var subexamples = new List<JObject>(examples.Length);
foreach (var obj in examples)
{
JToken value;
if (obj.TryGetValue(field.Key, out value))
{
if (value.Type == JTokenType.Object)
{
subexamples.Add((JObject)value);
}
}
}
fieldType.AssignName(CreateUniqueClassName(field.Key));
GenerateClass(subexamples.ToArray(), fieldType);
}
if (fieldType.InternalType != null && fieldType.InternalType.Type == JsonTypeEnum.Object)
{
var subexamples = new List<JObject>(examples.Length);
foreach (var obj in examples)
{
JToken value;
if (obj.TryGetValue(field.Key, out value))
{
if (value.Type == JTokenType.Array)
{
foreach (var item in (JArray)value)
{
if (!(item is JObject)) throw new NotSupportedException("Arrays of non-objects are not supported yet.");
subexamples.Add((JObject)item);
}
}
else if (value.Type == JTokenType.Object)
{
foreach (var item in (JObject)value)
{
if (!(item.Value is JObject)) throw new NotSupportedException("Arrays of non-objects are not supported yet.");
subexamples.Add((JObject)item.Value);
}
}
}
}
field.Value.InternalType.AssignName(CreateUniqueClassNameFromPlural(field.Key));
GenerateClass(subexamples.ToArray(), field.Value.InternalType);
}
}
type.Fields = jsonFields.Select(x => new FieldInfo(this, x.Key, x.Value, UsePascalCase, fieldExamples[x.Key])).ToArray();
Types.Add(type);
}