public static string GetInputType(ComponentCatalog catalog, Type inputType, GeneratedClasses generatedClasses, string rootNameSpace) { if (inputType.IsGenericType && inputType.GetGenericTypeDefinition() == typeof(Var <>)) { return($"Var<{GetCSharpTypeName(inputType.GetGenericTypeArgumentsEx()[0])}>"); } if (inputType.IsArray && Var <int> .CheckType(inputType.GetElementType())) { return($"ArrayVar<{GetCSharpTypeName(inputType.GetElementType())}>"); } if (inputType.IsGenericType && inputType.GetGenericTypeDefinition() == typeof(Dictionary <,>) && inputType.GetGenericTypeArgumentsEx()[0] == typeof(string)) { return($"DictionaryVar<{GetCSharpTypeName(inputType.GetGenericTypeArgumentsEx()[1])}>"); } if (Var <int> .CheckType(inputType)) { return($"Var<{GetCSharpTypeName(inputType)}>"); } var type = ExtractOptionalOrNullableType(inputType, out bool isNullable, out bool isOptional); var typeEnum = TlcModule.GetDataType(type); switch (typeEnum) { case TlcModule.DataKind.Float: case TlcModule.DataKind.Int: case TlcModule.DataKind.UInt: case TlcModule.DataKind.Char: case TlcModule.DataKind.String: case TlcModule.DataKind.Bool: case TlcModule.DataKind.DataView: case TlcModule.DataKind.TransformModel: case TlcModule.DataKind.PredictorModel: case TlcModule.DataKind.FileHandle: return(GetCSharpTypeName(inputType)); case TlcModule.DataKind.Array: return(GetInputType(catalog, inputType.GetElementType(), generatedClasses, rootNameSpace) + "[]"); case TlcModule.DataKind.Component: string kind; bool success = catalog.TryGetComponentKind(type, out kind); Contracts.Assert(success); return($"{kind}"); case TlcModule.DataKind.Enum: var enumName = generatedClasses.GetApiName(type, rootNameSpace); if (isNullable) { return($"{enumName}?"); } if (isOptional) { return($"Optional<{enumName}>"); } return($"{enumName}"); default: if (isNullable) { return(generatedClasses.GetApiName(type, rootNameSpace) + "?"); } if (isOptional) { return($"Optional<{generatedClasses.GetApiName(type, rootNameSpace)}>"); } return(generatedClasses.GetApiName(type, rootNameSpace)); } }
private void GenerateEnums(IndentingTextWriter writer, Type inputType, string currentNamespace) { foreach (var fieldInfo in inputType.GetFields()) { var inputAttr = fieldInfo.GetCustomAttributes(typeof(ArgumentAttribute), false).FirstOrDefault() as ArgumentAttribute; if (inputAttr == null || inputAttr.Visibility == ArgumentAttribute.VisibilityType.CmdLineOnly) { continue; } var type = CSharpGeneratorUtils.ExtractOptionalOrNullableType(fieldInfo.FieldType); if (_generatedClasses.IsGenerated(type.FullName)) { continue; } if (!type.IsEnum) { var typeEnum = TlcModule.GetDataType(type); if (typeEnum == TlcModule.DataKind.Unknown) { GenerateEnums(writer, type, currentNamespace); } continue; } var enumType = Enum.GetUnderlyingType(type); var apiName = _generatedClasses.GetApiName(type, currentNamespace); if (enumType == typeof(int)) { writer.WriteLine($"public enum {apiName}"); } else { Contracts.Assert(enumType == typeof(byte)); writer.WriteLine($"public enum {apiName} : byte"); } _generatedClasses.MarkAsGenerated(type.FullName); writer.Write("{"); writer.Indent(); var names = Enum.GetNames(type); var values = Enum.GetValues(type); string prefix = ""; for (int i = 0; i < names.Length; i++) { var name = names[i]; if (type.GetField(name).GetCustomAttribute <HideEnumValueAttribute>() != null) { continue; } var value = values.GetValue(i); writer.WriteLine(prefix); if (enumType == typeof(int)) { writer.Write($"{name} = {(int)value}"); } else { Contracts.Assert(enumType == typeof(byte)); writer.Write($"{name} = {(byte)value}"); } prefix = ","; } writer.WriteLine(); writer.Outdent(); writer.WriteLine("}"); writer.WriteLine(); } }
public static string GetValue(ComponentCatalog catalog, Type fieldType, object fieldValue, GeneratedClasses generatedClasses, string rootNameSpace) { if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Var <>)) { return($"new Var<{GetCSharpTypeName(fieldType.GetGenericTypeArgumentsEx()[0])}>()"); } if (fieldType.IsArray && Var <int> .CheckType(fieldType.GetElementType())) { return($"new ArrayVar<{GetCSharpTypeName(fieldType.GetElementType())}>()"); } if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Dictionary <,>) && fieldType.GetGenericTypeArgumentsEx()[0] == typeof(string)) { return($"new DictionaryVar<{GetCSharpTypeName(fieldType.GetGenericTypeArgumentsEx()[1])}>()"); } if (Var <int> .CheckType(fieldType)) { return($"new Var<{GetCSharpTypeName(fieldType)}>()"); } if (fieldValue == null) { return(null); } if (!fieldType.IsInterface) { try { var defaultFieldValue = Activator.CreateInstance(fieldType); if (defaultFieldValue == fieldValue) { return(null); } } catch (MissingMethodException) { // No parameterless constructor, ignore. } } var typeEnum = TlcModule.GetDataType(fieldType); fieldType = ExtractOptionalOrNullableType(fieldType, out bool isNullable, out bool isOptional); switch (typeEnum) { case TlcModule.DataKind.Array: var arr = fieldValue as Array; if (arr != null && arr.GetLength(0) > 0) { return($"{{ {string.Join(", ", arr.Cast<object>().Select(item => GetValue(catalog, fieldType.GetElementType(), item, generatedClasses, rootNameSpace)))} }}"); } return(null); case TlcModule.DataKind.String: var strval = fieldValue as string; if (strval != null) { return(Quote(strval)); } return(null); case TlcModule.DataKind.Float: if (fieldValue is double d) { if (double.IsPositiveInfinity(d)) { return("double.PositiveInfinity"); } if (double.IsNegativeInfinity(d)) { return("double.NegativeInfinity"); } if (d != 0) { return(d.ToString("R") + "d"); } } else if (fieldValue is float f) { if (float.IsPositiveInfinity(f)) { return("float.PositiveInfinity"); } if (float.IsNegativeInfinity(f)) { return("float.NegativeInfinity"); } if (f != 0) { return(f.ToString("R") + "f"); } } return(null); case TlcModule.DataKind.Int: if (fieldValue is int i) { if (i != 0) { return(i.ToString()); } } else if (fieldValue is long l) { if (l != 0) { return(l.ToString()); } } return(null); case TlcModule.DataKind.Bool: return((bool)fieldValue ? "true" : "false"); case TlcModule.DataKind.Enum: string enumAsString = fieldValue.ToString(); if (fieldType.GetField(enumAsString).GetCustomAttribute <HideEnumValueAttribute>() != null) { // The default value for the enum has the hiding attribute on it. We will search for // alternate names. Regrettably I see no way beyond a manual scan. string unhiddenName = Enum.GetNames(fieldType).Zip(Enum.GetValues(fieldType).Cast <object>(), (name, val) => (name, val)) .Where(pair => pair.val.Equals(fieldValue)) .Where(pair => fieldType.GetField(pair.name).GetCustomAttribute <HideEnumValueAttribute>() == null) .Select(pair => pair.name).FirstOrDefault(); enumAsString = unhiddenName ?? throw Contracts.Except($"Could not find unhidden alternative for '{fieldValue}' in type '{fieldType}'"); } if (generatedClasses.IsGenerated(fieldType.FullName)) { return(generatedClasses.GetApiName(fieldType, rootNameSpace) + "." + enumAsString); } else { return(generatedClasses.GetApiName(fieldType, "Runtime") + "." + enumAsString); } case TlcModule.DataKind.Char: return($"'{GetCharAsString((char)fieldValue)}'"); case TlcModule.DataKind.Component: var type = fieldValue.GetType(); ComponentCatalog.ComponentInfo componentInfo; if (!catalog.TryFindComponent(fieldType, type, out componentInfo)) { return(null); } object defaultComponent = null; try { defaultComponent = Activator.CreateInstance(componentInfo.ArgumentType); } catch (MissingMethodException) { // No parameterless constructor, ignore. } var propertyBag = new List <string>(); if (defaultComponent != null) { foreach (var fieldInfo in componentInfo.ArgumentType.GetFields()) { var inputAttr = fieldInfo.GetCustomAttributes(typeof(ArgumentAttribute), false).FirstOrDefault() as ArgumentAttribute; if (inputAttr == null || inputAttr.Visibility == ArgumentAttribute.VisibilityType.CmdLineOnly) { continue; } if (fieldInfo.FieldType == typeof(JArray) || fieldInfo.FieldType == typeof(JObject)) { continue; } var propertyValue = GetValue(catalog, fieldInfo.FieldType, fieldInfo.GetValue(fieldValue), generatedClasses, rootNameSpace); var defaultPropertyValue = GetValue(catalog, fieldInfo.FieldType, fieldInfo.GetValue(defaultComponent), generatedClasses, rootNameSpace); if (propertyValue != defaultPropertyValue) { propertyBag.Add($"{Capitalize(inputAttr.Name ?? fieldInfo.Name)} = {propertyValue}"); } } } var properties = propertyBag.Count > 0 ? $" {{ {string.Join(", ", propertyBag)} }}" : ""; return($"new {GetComponentName(componentInfo)}(){properties}"); case TlcModule.DataKind.Unknown: return($"new {generatedClasses.GetApiName(fieldType, rootNameSpace)}()"); default: return(fieldValue.ToString()); } }