Ejemplo n.º 1
0
        static IEnumerable <string> GetRegisterCollectionTypeMethod(PropertyBagDefinition propertyBag)
        {
            var visited = new HashSet <ITypeSymbol>();

            foreach (var property in propertyBag.GetPropertyMembers())
            {
                foreach (var line in GetRegisterCollectionTypesRecurse(propertyBag.ContainerType, property.MemberType, visited))
                {
                    yield return(line);
                }
            }
        }
Ejemplo n.º 2
0
        public static ClassDeclarationSyntax CreatePropertyBagClassDeclarationSyntax(PropertyBagDefinition propertyBag)
        {
            var builder = new StringBuilder();

            builder.AppendLine($"[System.Runtime.CompilerServices.CompilerGenerated]");
            builder.AppendLine($"class {propertyBag.PropertyBagClassName} : Unity.Properties.ContainerPropertyBag<{propertyBag.ContainerTypeName}>");
            builder.AppendLine($"{{");

            builder.AppendLine($"public {propertyBag.PropertyBagClassName}()");
            builder.AppendLine($"{{");
            foreach (var property in propertyBag.GetValidPublicPropertyMembers())
            {
                builder.Append($"AddProperty(new ").Append(property.PropertyClassName).AppendLine("());");
            }

            if (propertyBag.GetValidNonPublicPropertyMembers().Any())
            {
                builder.AppendLine($"#if !{Defines.NET_DOTS}");
                foreach (var property in propertyBag.GetValidNonPublicPropertyMembers())
                {
                    builder.Append($"AddProperty(new ").Append(property.PropertyClassName).AppendLine("());");
                }
                builder.AppendLine($"#endif");
            }

            foreach (var registerCollectionTypeMethod in GetRegisterCollectionTypeMethod(propertyBag))
            {
                builder.AppendLine(registerCollectionTypeMethod);
            }

            builder.Append($"}}");

            foreach (var property in propertyBag.GetValidPublicPropertyMembers())
            {
                builder.AppendLine($"[System.Runtime.CompilerServices.CompilerGenerated]");
                builder.AppendLine($"class {property.PropertyClassName} : Unity.Properties.Property<{propertyBag.ContainerTypeName}, {property.PropertyTypeName}>");
                builder.AppendLine($"{{");
                builder.AppendLine($"public override string Name => \"{property.PropertyName}\";");
                builder.AppendLine($"public override bool IsReadOnly => {property.IsReadOnly.ToString().ToLower()};");

                if (property.HasCustomAttributes)
                {
                    builder.AppendLine($"public {property.PropertyClassName}()");
                    builder.AppendLine($"{{");
                    builder.AppendLine($"#if !{Defines.NET_DOTS}");
                    var getMemberMethod = property.IsField ? "GetField" : "GetProperty";
                    builder.AppendLine($"AddAttributes(typeof({propertyBag.ContainerTypeName}).{getMemberMethod}(\"{property.MemberName}\", BindingFlags.Instance | BindingFlags.Public).GetCustomAttributes());");
                    builder.AppendLine($"#endif");
                    builder.AppendLine($"}}");
                }

                builder.AppendLine($"public override {property.PropertyTypeName} GetValue(ref {propertyBag.ContainerTypeName} container) => container.{property.PropertyName};");

                builder.AppendLine(property.IsReadOnly
                    ? $"public override void SetValue(ref {propertyBag.ContainerTypeName} container, {property.PropertyTypeName} value) => throw new System.InvalidOperationException(\"Property is ReadOnly\");"
                    : $"public override void SetValue(ref {propertyBag.ContainerTypeName} container, {property.PropertyTypeName} value) => container.{property.PropertyName} = value;");

                builder.AppendLine($"}}");
            }

            if (propertyBag.GetValidNonPublicPropertyMembers().Any())
            {
                builder.AppendLine($"#if !{Defines.NET_DOTS}");
                foreach (var property in propertyBag.GetValidNonPublicPropertyMembers())
                {
                    var getMemberMethod = property.IsField ? "GetField" : "GetProperty";
                    builder.AppendLine($"[System.Runtime.CompilerServices.CompilerGenerated]");
                    builder.AppendLine($"class {property.PropertyClassName} : Unity.Properties.ReflectedMemberProperty<{propertyBag.ContainerTypeName}, {property.PropertyTypeName}>");
                    builder.AppendLine($"{{");
                    builder.AppendLine($"    public {property.PropertyClassName}()");
                    builder.AppendLine($"        : base(typeof({property.MemberSymbol.ContainingType}).{getMemberMethod}(\"{property.MemberName}\", BindingFlags.Instance | BindingFlags.NonPublic), \"{property.PropertyName}\")");
                    builder.AppendLine($"    {{");
                    builder.AppendLine($"    }}");
                    builder.AppendLine($"}}");
                }
                builder.AppendLine($"#endif");
            }

            builder.AppendLine($"}}");

            var propertyBagClassDeclarationSyntax = SyntaxFactory.ParseMemberDeclaration(builder.ToString()) as ClassDeclarationSyntax;

            if (null == propertyBagClassDeclarationSyntax)
            {
                throw new Exception($"Failed to construct ClassDeclarationSyntax for ContainerType=[{propertyBag.ContainerTypeName}]");
            }

            return(propertyBagClassDeclarationSyntax);
        }