示例#1
0
        static void CreateComponents(Type type, bool isRoot, string rootOutputDirectory, AppSettings settings)
        {
            string typeName = type.Name;
            string path     = Path.Combine(rootOutputDirectory, settings.Components.Path, $"{type.Name}.cs");

            if (File.Exists(path))
            {
                File.Delete(path);
            }
            string tElement                    = type.IsSealed ? $"global::{GetTypeFullName(type)}" : "TElement";
            string superClass                  = GetBaseClassForComponents(isRoot, type.BaseType, settings.Components.RootElement, tElement);
            var    properties                  = GetTypeProperties(type);
            var    events                      = GetTypeEvents(type);
            var    genericTypeParameters       = type.GetTypeInfo().GenericTypeParameters;
            bool   isAbstract                  = IsTypeAbstract(type, settings.Components.ElementsRequiresConstructor);
            string additionalGenericParameters = $"{string.Join(", ", genericTypeParameters.Select(p => p.Name))}{(genericTypeParameters.Length > 0 ? ", " : "")}";
            var    sb = new LevelStringBuilder(new StringBuilder());

            if (settings.Components.Namespaces != null)
            {
                foreach (string ns in settings.Components.Namespaces)
                {
                    sb.AppendLine($"using {ns};");
                }
            }
            sb.AppendLine();
            string classPureName                   = GetPureName(type.Name);
            var    containerProperties             = properties.Where(p => IsContainerProperty(p, settings.Properties)).ToArray();
            var    contentProperties               = properties.Where(p => IsContentProperty(p, settings.Properties)).ToArray();
            var    nonContentOrContainerProperties = properties.Except(containerProperties).Except(contentProperties).ToArray();
            bool   isContainerByInterface          = IsContainerByInterface(type, settings.ContainerInterfaces);

            using (sb.AddMethod($"namespace {settings.Namespace}.Components"))
            {
                sb.AppendLine($"public {(isAbstract ? "abstract" : "")} partial class {classPureName}<{additionalGenericParameters}TProps{(type.IsSealed ? "" : ", TElement")}>: {superClass}");
                using (sb.AddLevel())
                {
                    sb.AppendLine($"where TProps : Props.{GetTypeName(type)}");
                    if (!type.IsSealed)
                    {
                        string newConstraint = settings.Components.ElementsRequiresConstructor ? ", new()" : "";
                        sb.AppendLine($"where TElement : global::{GetTypeFullName(type)}{newConstraint}");
                    }
                    foreach (var genericParameter in type.GetTypeInfo().GenericTypeParameters)
                    {
                        var constraints = genericParameter.GetGenericParameterConstraints();
                        if (constraints.Length > 0)
                        {
                            sb.AppendLine($"where {genericParameter.Name}: {string.Join(", ", constraints.Select(c => $"global::{c.FullName}"))} ");
                        }
                    }
                }
                sb.Open();
                using (sb.AddLevel())
                {
                    // CreateElement
                    if (!isAbstract)
                    {
                        var source = type.IsSealed ? settings.Components.SealedElementCreation : settings.Components.ElementCreation;
                        if (source?.Length > 0)
                        {
                            string elementType = $"global::{GetTypeFullName(type)}";
                            foreach (string line in source)
                            {
                                sb.AppendLine(line.Replace("[TElement]", elementType));
                            }
                        }
                        if (settings.Components.InitElementPartial)
                        {
                            sb.AppendLine($"partial void InitElement({tElement} element);");
                        }
                    }
                    if (properties.Length > 0 || isContainerByInterface)
                    {
                        using (sb.AddMethod($"public override void AssignProperties(ISharpRenderer<global::{settings.RootType.Name}> renderer, int level, NewState newState, TProps previous, TProps nextProps)"))
                        {
                            sb.AppendLine($"base.AssignProperties(renderer, level, newState, previous, nextProps);");
                            if (nonContentOrContainerProperties.Length > 0)
                            {
                                sb.AppendLine($"Update{classPureName}WithInstanceProperties(Element, previous, nextProps);");
                            }
                            foreach (var p in contentProperties)
                            {
                                using (sb.AddMethod($"if (nextProps.{p.Name} != null)"))
                                {
                                    sb.AppendLine($"Element.{p.Name} = renderer.ProcessPair(level + 1, newState, previous?.{p.Name}, nextProps.{p.Name});");
                                }
                            }
                            if (containerProperties.Length > 0 || isContainerByInterface)
                            {
                                string propertyName;
                                if (containerProperties.Length > 0)
                                {
                                    propertyName = containerProperties[0].Name;
                                }
                                else
                                {
                                    propertyName = settings.CustomContainerProperty;
                                }
                                sb.AppendLine($"AssignContainerProperties(renderer, level, newState, previous?.{propertyName}, nextProps.{propertyName}, nameof({settings.Namespace}.{settings.Properties.Path}.{GetPureName(type.Name)}.{propertyName}), nameof({settings.Namespace}.{settings.Properties.Path}.{GetPureName(type.Name)}));");
                            }
                            //if (isContainerByInterface)
                            //{
                            //    string propName = settings.CustomContainerProperty;
                            //    string sourceTypeName = $"{settings.Namespace}.{settings.Properties.Path}.{GetPureName(type.Name)}";
                            //    sb.Open();
                            //    using (sb.AddLevel())
                            //    {
                            //        sb.AppendLine("var elements = renderer.VisitAllCollection(level, newState, previous, nextProps, propertyName, containerName);");
                            //        sb.AppendLine($"{settings.Components.ElementsSynchronization}");
                            //    }
                            //    sb.Close();
                            //}
                            if (settings.Components.PostAssignPropertiesPartial)
                            {
                                sb.AppendLine($"PostAssign{classPureName}Properties(renderer, level, newState, previous, nextProps);");
                            }
                        }
                        if (containerProperties.Length > 0 || isContainerByInterface)
                        {
                            using (sb.AddMethod($"public override void AssignContainerProperties(ISharpRenderer<global::{settings.RootType.Name}> renderer, int level, NewState newState, List<ISharpProp> previous, List<ISharpProp> nextProps, string propertyName, string containerName)"))
                            {
                                //foreach (var p in containerProperties)
                                //{
                                //sb.Open();
                                //using (sb.AddLevel())
                                //{
                                sb.AppendLine($"var elements = renderer.VisitAllCollection(level, newState, previous, nextProps, propertyName, containerName);");
                                sb.AppendLine($"{settings.Components.ElementsSynchronization}");
                                //}
                                //sb.Close();
                                //}
                            }
                        }
                    }
                    if (settings.Components.PostAssignPropertiesPartial)
                    {
                        sb.AppendLine($"partial void PostAssign{classPureName}Properties(ISharpRenderer<global::Android.Views.View> renderer, int level, NewState newState, TProps previous, TProps nextProps);");
                    }
                    if (nonContentOrContainerProperties.Length > 0)
                    {
                        using (sb.AddMethod($"protected override void UpdateElement(ISharpRenderer renderer, {tElement} element, TProps props)"))
                        {
                            sb.AppendLine("base.UpdateElement(renderer, element, props);");
                            sb.AppendLine($"Update{classPureName}WithInstanceProperties(element, null, props);");
                        }
                        using (sb.AddMethod($"static void Update{classPureName}WithInstanceProperties({tElement} element, TProps previous, TProps nextProps)"))
                        {
                            foreach (var p in nonContentOrContainerProperties)
                            {
                                if (!IsContentProperty(p, settings.Properties) && !IsContainerProperty(p, settings.Properties))
                                {
                                    using (sb.AddMethod($"if (nextProps.{p.Name}.HasValue)"))
                                    {
                                        sb.AppendLine($"element.{p.Name} = nextProps.{p.Name}.Value.Value;");
                                    }
                                }
                            }
                            foreach (var e in events)
                            {
                                using (sb.AddMethod($"if (!(previous?.{e.Name} is null) && nextProps.{e.Name} is null)"))
                                {
                                    sb.AppendLine($"element.{e.Name} -= nextProps.{e.Name};");
                                }
                                using (sb.AddMethod($"if (previous?.{e.Name} is null && !(nextProps.{e.Name} is null))"))
                                {
                                    sb.AppendLine($"element.{e.Name} += nextProps.{e.Name};");
                                }
                            }
                        }
                    }
                }
                sb.Close();
            }
            File.WriteAllText(path, sb.ToString());
        }
示例#2
0
 public Method(LevelStringBuilder sb) : base(sb)
 {
     sb.Open();
 }
示例#3
0
        static void CreateProperties(Type type, bool isRoot, string rootOutputDirectory, string rootNamespace, AppSettings appSettings)
        {
            var    settings = appSettings.Properties;
            string path     = Path.Combine(rootOutputDirectory, settings.Path, $"{type.Name}.cs");

            if (File.Exists(path))
            {
                File.Delete(path);
            }
            string superClass            = GetBaseClassForProperties(isRoot, type.BaseType);
            var    properties            = GetTypeProperties(type);
            var    events                = GetTypeEvents(type);
            var    lastProperty          = properties.LastOrDefault();
            var    sb                    = new LevelStringBuilder(new StringBuilder());
            bool   isAbstract            = IsTypeAbstract(type, appSettings.Components.ElementsRequiresConstructor);
            string abstractType          = isAbstract ? " abstract" : "";
            string implementedInterfaces = "";

            if (settings.Namespaces != null)
            {
                foreach (string ns in settings.Namespaces)
                {
                    sb.AppendLine($"using {ns};");
                }
            }
            sb.AppendLine();
            using (sb.AddMethod($"namespace {rootNamespace}.Props"))
            {
                sb.AppendLine($"public{abstractType} partial class {GetTypeName(type)}: {superClass}{implementedInterfaces}");
                foreach (var genericParameter in type.GetTypeInfo().GenericTypeParameters)
                {
                    var constraints = genericParameter.GetGenericParameterConstraints();
                    {
                        if (constraints.Length > 0)
                        {
                            using (sb.AddLevel())
                            {
                                sb.AppendLine($"where {genericParameter.Name}: {string.Join(", ", constraints.Select(c => $"global::{c.FullName}"))} ");
                            }
                        }
                    }
                }
                sb.Open();
                using (sb.AddLevel())
                {
                    var    contentProperties      = new List <PropertyInfo>();
                    var    containerProperties    = new List <PropertyInfo>();
                    var    containerPropertyNames = new List <string>();
                    string typeName = type.Name;
                    foreach (var p in properties)
                    {
                        if (IsContentProperty(p, settings))
                        {
                            contentProperties.Add(p);
                            sb.AppendLine($"public ISharpProp {p.Name} {{ get; set; }}");
                        }
                        else if (IsContainerProperty(p, settings) || IsListProperty(p.PropertyType))
                        {
                            containerProperties.Add(p);
                            containerPropertyNames.Add(p.Name);
                            sb.AppendLine($"public List<ISharpProp> {p.Name} {{ get; set; }} = new List<ISharpProp>();");
                        }
                        else
                        {
                            sb.AppendLine($"public ReactParam<{GetPropertyType(p.PropertyType)}>? {p.Name} {{ get; set; }}");
                        }
                    }
                    bool hasContainerByProperty = IsContainerByInterface(type, appSettings.ContainerInterfaces);
                    if (hasContainerByProperty)
                    {
                        containerPropertyNames.Add(appSettings.CustomContainerProperty);
                        sb.AppendLine($"public List<ISharpProp> {appSettings.CustomContainerProperty} {{ get; set; }} = new List<ISharpProp>();");
                    }
                    foreach (var e in events)
                    {
                        sb.AppendLine($"public {GetEventTypeFullName(e.EventHandlerType)} {e.Name} {{ get; set; }}");
                    }
                    if (!isAbstract)
                    {
                        using (sb.AddMethod("protected override ISharpStatefulComponent CreateComponent()"))
                        {
                            string tElement = type.IsSealed ? "" : $", global::{GetTypeFullName(type)}";
                            string additionalTypeParameters = type.IsGenericType ? string.Join(",", type.GetTypeInfo().GenericTypeParameters.Select(a => a.Name)) + ", " : "";
                            sb.AppendLine($"return new Components.{GetPureName(type.Name)}<{additionalTypeParameters}{GetTypeName(type)}{tElement}>();");
                        }
                    }
                    if (contentProperties.Count + containerProperties.Count > 0)
                    {
                        using (sb.AddMethod("protected override void UnmountComponent()"))
                        {
                            foreach (var p in contentProperties)
                            {
                                sb.AppendLine($"UnmountComponent({p.Name});");
                            }
                            foreach (var p in containerProperties)
                            {
                                sb.AppendLine($"UnmountComponents({p.Name});");
                            }
                            if (hasContainerByProperty)
                            {
                                sb.AppendLine($"UnmountComponents({appSettings.CustomContainerProperty});");
                            }
                            sb.AppendLine("base.UnmountComponent();");
                        }
                    }
                    if (properties.Length > 0)
                    {
                        using (sb.AddMethod($"public override IEnumerable<IReactParam> AllProperties"))
                        {
                            using (sb.AddMethod("get"))
                            {
                                foreach (var p in properties)
                                {
                                    sb.AppendLine($"yield return {p.Name};");
                                }
                                using (sb.AddMethod("foreach (var p in base.AllProperties)"))
                                {
                                    sb.AppendLine("yield return p;");
                                }
                            }
                        }
                    }
                    if (contentProperties.Count + containerProperties.Count > 0 || hasContainerByProperty)
                    {
                        using (sb.AddMethod("public override IEnumerable<ISharpProp> AllChildren"))
                        {
                            using (sb.AddMethod("get"))
                            {
                                List <string> containerPropertiesNames = new List <string>(containerProperties.Select(p => p.Name));
                                if (hasContainerByProperty)
                                {
                                    containerPropertiesNames.Add(appSettings.CustomContainerProperty);
                                }

                                foreach (var c in containerPropertiesNames)
                                {
                                    using (sb.AddMethod($"foreach (var c in {c})"))
                                    {
                                        sb.AppendLine("yield return c;");
                                    }
                                }
                                foreach (var c in contentProperties)
                                {
                                    sb.AppendLine($"yield return {c.Name};");
                                }
                                using (sb.AddMethod("foreach (var c in base.AllChildren)"))
                                {
                                    sb.AppendLine("yield return c;");
                                }
                            }
                        }
                    }
                    if (containerPropertyNames.Count > 0)
                    {
                        foreach (var name in containerPropertyNames)
                        {
                            sb.AppendLine($"public IEnumerable<ISharpProp> Add{name} {{ set => {name}.AddRange(value); }}");
                        }
                    }
                }
                sb.Close();
            }
            File.WriteAllText(path, sb.ToString());
        }