private void GenerateComponent(IndentingTextWriter writer, ComponentCatalog.ComponentInfo component, ComponentCatalog catalog)
 {
     GenerateEnums(writer, component.ArgumentType, "Runtime");
     writer.WriteLine();
     GenerateClasses(writer, component.ArgumentType, catalog, "Runtime");
     writer.WriteLine();
     CSharpGeneratorUtils.GenerateSummary(writer, component.Description);
     writer.WriteLine($"public sealed class {CSharpGeneratorUtils.GetComponentName(component)} : {component.Kind}");
     writer.WriteLine("{");
     writer.Indent();
     GenerateInputFields(writer, component.ArgumentType, catalog, "Runtime");
     writer.WriteLine($"internal override string ComponentName => \"{component.Name}\";");
     writer.Outdent();
     writer.WriteLine("}");
     writer.WriteLine();
 }
示例#2
0
        private static JObject BuildComponentManifest(IExceptionContext ectx, ComponentCatalog.ComponentInfo componentInfo, ComponentCatalog catalog)
        {
            Contracts.AssertValueOrNull(ectx);
            ectx.AssertValue(componentInfo);
            ectx.AssertValue(catalog);
            var result = new JObject();

            result[FieldNames.Name]         = componentInfo.Name;
            result[FieldNames.Desc]         = componentInfo.Description;
            result[FieldNames.FriendlyName] = componentInfo.FriendlyName;
            if (Utils.Size(componentInfo.Aliases) > 0)
            {
                result[FieldNames.Aliases] = new JArray(componentInfo.Aliases);
            }

            result[FieldNames.Settings] = BuildInputManifest(ectx, componentInfo.ArgumentType, catalog);
            return(result);
        }
示例#3
0
        public JObject GetJsonObject(object instance, Dictionary <string, List <ParameterBinding> > inputBindingMap, Dictionary <ParameterBinding, VariableBinding> inputMap)
        {
            Contracts.CheckValue(instance, nameof(instance));
            Contracts.Check(instance.GetType() == _type);

            var result   = new JObject();
            var defaults = Activator.CreateInstance(_type);

            for (int i = 0; i < _fields.Length; i++)
            {
                var field       = _fields[i];
                var attr        = _attrs[i];
                var instanceVal = field.GetValue(instance);
                var defaultsVal = field.GetValue(defaults);

                if (inputBindingMap.TryGetValue(field.Name, out List <ParameterBinding> bindings))
                {
                    // Handle variables.
                    Contracts.Assert(bindings.Count > 0);
                    VariableBinding varBinding;
                    var             paramBinding = bindings[0];
                    if (paramBinding is SimpleParameterBinding)
                    {
                        Contracts.Assert(bindings.Count == 1);
                        bool success = inputMap.TryGetValue(paramBinding, out varBinding);
                        Contracts.Assert(success);
                        Contracts.AssertValue(varBinding);

                        result.Add(field.Name, new JValue(varBinding.ToJson()));
                    }
                    else if (paramBinding is ArrayIndexParameterBinding)
                    {
                        // Array parameter bindings.
                        var array = new JArray();
                        foreach (var parameterBinding in bindings)
                        {
                            Contracts.Assert(parameterBinding is ArrayIndexParameterBinding);
                            bool success = inputMap.TryGetValue(parameterBinding, out varBinding);
                            Contracts.Assert(success);
                            Contracts.AssertValue(varBinding);
                            array.Add(new JValue(varBinding.ToJson()));
                        }

                        result.Add(field.Name, array);
                    }
                    else
                    {
                        // Dictionary parameter bindings. Not supported yet.
                        Contracts.Assert(paramBinding is DictionaryKeyParameterBinding);
                        throw Contracts.ExceptNotImpl("Dictionary of variables not yet implemented.");
                    }
                }
                else if (instanceVal == null && defaultsVal != null)
                {
                    // Handle null values.
                    result.Add(field.Name, new JValue(instanceVal));
                }
                else if (instanceVal != null && (attr.Input.IsRequired || !instanceVal.Equals(defaultsVal)))
                {
                    // A required field will be serialized regardless of whether or not its value is identical to the default.
                    var type = instanceVal.GetType();
                    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Optional <>))
                    {
                        var isExplicit = ExtractOptional(ref instanceVal, ref type);
                        if (!isExplicit)
                        {
                            continue;
                        }
                    }

                    if (type == typeof(JArray))
                    {
                        result.Add(field.Name, (JArray)instanceVal);
                    }
                    else if (type.IsGenericType &&
                             ((type.GetGenericTypeDefinition() == typeof(Var <>)) ||
                              type.GetGenericTypeDefinition() == typeof(ArrayVar <>) ||
                              type.GetGenericTypeDefinition() == typeof(DictionaryVar <>)))
                    {
                        result.Add(field.Name, new JValue($"${((IVarSerializationHelper)instanceVal).VarName}"));
                    }
                    else if (type == typeof(bool) ||
                             type == typeof(string) ||
                             type == typeof(char) ||
                             type == typeof(double) ||
                             type == typeof(float) ||
                             type == typeof(int) ||
                             type == typeof(long) ||
                             type == typeof(uint) ||
                             type == typeof(ulong))
                    {
                        // Handle simple types.
                        result.Add(field.Name, new JValue(instanceVal));
                    }
                    else if (type.IsEnum)
                    {
                        // Handle enums.
                        result.Add(field.Name, new JValue(instanceVal.ToString()));
                    }
                    else if (type.IsArray)
                    {
                        // Handle arrays.
                        var array       = (Array)instanceVal;
                        var jarray      = new JArray();
                        var elementType = type.GetElementType();
                        if (elementType == typeof(bool) ||
                            elementType == typeof(string) ||
                            elementType == typeof(char) ||
                            elementType == typeof(double) ||
                            elementType == typeof(float) ||
                            elementType == typeof(int) ||
                            elementType == typeof(long) ||
                            elementType == typeof(uint) ||
                            elementType == typeof(ulong))
                        {
                            foreach (object item in array)
                            {
                                jarray.Add(new JValue(item));
                            }
                        }
                        else
                        {
                            var builder = new InputBuilder(_ectx, elementType, _catalog);
                            foreach (object item in array)
                            {
                                jarray.Add(builder.GetJsonObject(item, inputBindingMap, inputMap));
                            }
                        }
                        result.Add(field.Name, jarray);
                    }
                    else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary <,>) &&
                             type.GetGenericArguments()[0] == typeof(string))
                    {
                        // Handle dictionaries.
                        // REVIEW: Needs to be implemented when we will have entry point arguments that contain dictionaries.
                    }
                    else if (typeof(IComponentFactory).IsAssignableFrom(type))
                    {
                        // Handle component factories.
                        bool success = _catalog.TryFindComponent(type, out ComponentCatalog.ComponentInfo instanceInfo);
                        Contracts.Assert(success);
                        var builder      = new InputBuilder(_ectx, type, _catalog);
                        var instSettings = builder.GetJsonObject(instanceVal, inputBindingMap, inputMap);

                        ComponentCatalog.ComponentInfo defaultInfo = null;
                        JObject defSettings = new JObject();
                        if (defaultsVal != null)
                        {
                            var deftype = defaultsVal.GetType();
                            if (deftype.IsGenericType && deftype.GetGenericTypeDefinition() == typeof(Optional <>))
                            {
                                ExtractOptional(ref defaultsVal, ref deftype);
                            }
                            success = _catalog.TryFindComponent(deftype, out defaultInfo);
                            Contracts.Assert(success);
                            builder     = new InputBuilder(_ectx, deftype, _catalog);
                            defSettings = builder.GetJsonObject(defaultsVal, inputBindingMap, inputMap);
                        }

                        if (instanceInfo.Name != defaultInfo?.Name || instSettings.ToString() != defSettings.ToString())
                        {
                            var jcomponent = new JObject
                            {
                                { FieldNames.Name, new JValue(instanceInfo.Name) }
                            };
                            if (instSettings.ToString() != defSettings.ToString())
                            {
                                jcomponent.Add(FieldNames.Settings, instSettings);
                            }
                            result.Add(field.Name, jcomponent);
                        }
                    }
                    else
                    {
                        // REVIEW: pass in the bindings once we support variables in inner fields.

                        // Handle structs.
                        var builder = new InputBuilder(_ectx, type, _catalog);
                        result.Add(field.Name, builder.GetJsonObject(instanceVal, new Dictionary <string, List <ParameterBinding> >(),
                                                                     new Dictionary <ParameterBinding, VariableBinding>()));
                    }
                }
            }

            return(result);
        }
示例#4
0
 public static string GetComponentName(ComponentCatalog.ComponentInfo component)
 {
     return($"{Capitalize(component.Name)}{component.Kind}");
 }