public CSharpApiGenerator(IHostEnvironment env, Arguments args, string regenerate)
        {
            Contracts.CheckValue(env, nameof(env));
            _host = env.Register(RegistrationName);
            _host.AssertValue(args, nameof(args));
            _host.AssertNonEmpty(regenerate, nameof(regenerate));
            Utils.CheckOptionalUserDirectory(args.CsFilename, nameof(args.CsFilename));

            _csFilename = args.CsFilename;
            if (string.IsNullOrWhiteSpace(_csFilename))
            {
                _csFilename = "CSharpApi.cs";
            }
            _regenerate       = regenerate;
            _excludedSet      = new HashSet <string>(args.Exclude);
            _generatedClasses = new GeneratedClasses();
        }
Exemplo n.º 2
0
        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));
            }
        }
Exemplo n.º 3
0
        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, "") + "." + 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());
            }
        }