Example #1
0
        private static string GenerateInitializerFromProperty(
            PropertyTypeNode.TypeTag containerTypeTag,
            PropertyTypeNode propertyType)
        {
            // No initializer for structs
            if (containerTypeTag == PropertyTypeNode.TypeTag.Struct)
            {
                return(string.Empty);
            }

            var type = TypeDeclarationStringForProperty(propertyType);

            if (PropertyTypeNode.IsEnumerableType(propertyType.Tag) || propertyType.Tag == PropertyTypeNode.TypeTag.Struct)
            {
                // TODO value type etc.
                return($"new {type} {{}}");
            }

            if (propertyType.Tag == PropertyTypeNode.TypeTag.Class)
            {
                return($"new {type} ()");
            }

            return(!string.IsNullOrEmpty(propertyType.DefaultValue)
                ? propertyType.DefaultValue
                : string.Empty);
        }
Example #2
0
        private static string GetPropertyWrapperTypeFor(
            string containerName,
            PropertyTypeNode.TypeTag containerTypeTag,
            PropertyTypeNode propertyType)
        {
            // @TODO warning we rely on type definitions here

            var propertyWrapperTypeStringPrefix = "";

            if (containerTypeTag.HasFlag(PropertyTypeNode.TypeTag.Struct))
            {
                propertyWrapperTypeStringPrefix = "Struct";
            }

            switch (propertyType.Tag)
            {
            case PropertyTypeNode.TypeTag.Struct:
                return($"{propertyWrapperTypeStringPrefix}MutableContainerProperty<{containerName}, {propertyType.TypeName}>");

            case PropertyTypeNode.TypeTag.Class:
                return($"{propertyWrapperTypeStringPrefix}ContainerProperty<{containerName}, {propertyType.TypeName}>");

            case PropertyTypeNode.TypeTag.Enum:
                return($"{propertyWrapperTypeStringPrefix}EnumProperty<{containerName}, {propertyType.TypeName}>");

            case PropertyTypeNode.TypeTag.List:
            {
                var t = TypeStringFromEnumerableProperty(propertyType);

                switch (propertyType.Of.Tag)
                {
                case PropertyTypeNode.TypeTag.Primitive:
                    return($"{propertyWrapperTypeStringPrefix}ListProperty<{containerName}, {t}, {propertyType.Of.TypeName}>");

                case PropertyTypeNode.TypeTag.Struct:
                    return($"{propertyWrapperTypeStringPrefix}MutableContainerListProperty<{containerName}, {t}, {propertyType.Of.TypeName}>");

                case PropertyTypeNode.TypeTag.Class:
                    return($"{propertyWrapperTypeStringPrefix}ContainerListProperty<{containerName}, {t}, {propertyType.Of.TypeName}>");

                case PropertyTypeNode.TypeTag.Enum:
                    return($"{propertyWrapperTypeStringPrefix}EnumListProperty<{containerName}, {t}, {propertyType.Of.TypeName}>");

                case PropertyTypeNode.TypeTag.Unknown:
                case PropertyTypeNode.TypeTag.List:
                default:
                    throw new Exception($"Invalid property tag of list property name {propertyType.PropertyName}");
                }
            }

            case PropertyTypeNode.TypeTag.Primitive:
                return($"{propertyWrapperTypeStringPrefix}Property<{containerName}, {propertyType.TypeName}>");

            default:
                break;
            }

            return($"{propertyWrapperTypeStringPrefix}Property<{containerName}, {propertyType.TypeName}>");
        }
Example #3
0
        private static string GeneratePropertyWrapperInitializers(
            PropertyTypeNode propertyType,
            string containerName,
            PropertyTypeNode.TypeTag containerTypeTag,
            string propertyWrapperTypeString,
            string propertyAccessorName,
            string propertyTypeString,
            Scope code
            )
        {
            var initializerParams = new List <string>();

            var accessors = GetPropertyWrapperAccessors(
                propertyType,
                containerName,
                containerTypeTag,
                propertyWrapperTypeString,
                propertyTypeString,
                propertyAccessorName);

            // @TODO shouldn't be done here, and be located in a cleaner place

#if ENABLE_CUSTOM_PROPERTY_PARTIALS
            if (propertyType.IsCustomProperty)
            {
                var containerAsAParemeterType =
                    containerTypeTag.HasFlag(PropertyTypeNode.TypeTag.Struct) ? $"ref {containerName}" : $"{containerName}";

                code.AddLine("");

                if (!string.IsNullOrEmpty(accessors.RefGetter))
                {
                    code.AddLine(
                        $"partial void {accessors.RefGetter}({containerAsAParemeterType} value, IPropertyVisitor visitor);");
                }

                code.AddLine($"partial void {accessors.ValueSetter}({containerAsAParemeterType} container, {propertyTypeString} value);");

                code.AddLine(
                    $"partial {propertyTypeString} {accessors.ValueGetter}({containerAsAParemeterType} container);");

                code.AddLine("");
            }
#endif

            initializerParams.Add($"nameof({propertyType.PropertyName})");
            initializerParams.Add(accessors.ValueGetter);
            initializerParams.Add(accessors.ValueSetter);

            if (!string.IsNullOrEmpty(accessors.RefGetter))
            {
                initializerParams.Add(accessors.RefGetter);
            }

            return($@"new { propertyWrapperTypeString }( {string.Join(", ", initializerParams)} )");
        }
        private PropertyTypeNode.TypeTag GetTypeTagFromPropertyName(
            string propertyTypeName,
            ContainerTypeTreePath context,
            PropertyTypeNode.TypeTag defaultTypeTag = PropertyTypeNode.TypeTag.Class)
        {
            var propertyTypeTag = defaultTypeTag;

            if (TypeResolver.IsPrimitiveType(propertyTypeName))
            {
                propertyTypeTag = PropertyTypeNode.TypeTag.Primitive;
            }
            else if (_typeResolver != null)
            {
                propertyTypeTag = _typeResolver.Resolve(context, propertyTypeName);
            }
            return(propertyTypeTag);
        }
Example #5
0
        private static PropertyWrapperAccessors GetPropertyWrapperAccessors(
            PropertyTypeNode propertyType,
            string containerName,
            PropertyTypeNode.TypeTag containerTypeTag,
            string propertyWrapperTypeString,
            string propertyTypeString,
            string propertyAccessorName)
        {
            if (propertyType.IsCustomProperty)
            {
                return(new PropertyWrapperAccessors()
                {
                    ValueGetter = $"GetValue_{CleanupNameForMethod(propertyType.PropertyName)}",
                    ValueSetter = $"SetValue_{CleanupNameForMethod(propertyType.PropertyName)}",
                    RefGetter = propertyType.Tag == PropertyTypeNode.TypeTag.Struct
                        ? $"GetRef_{CleanupNameForMethod(propertyType.PropertyName)}"
                        : string.Empty
                });
            }

            var containerAsAParemeterType =
                containerTypeTag.HasFlag(PropertyTypeNode.TypeTag.Struct) ? $"ref {containerName}" : $"{containerName}";

            var propertySetter = "/* SET */ null";

            if (!PropertyTypeNode.IsCompositeType(propertyType.Tag) && !propertyType.IsReadonly)
            {
                propertySetter = $"/* SET */ ({containerAsAParemeterType} container, {propertyTypeString} value) => container.{propertyAccessorName} = value";
            }

            var propertyRefGetter = string.Empty;

            if (propertyType.Tag == PropertyTypeNode.TypeTag.Struct)
            {
                propertyRefGetter = $"/* REF */ ({containerAsAParemeterType} container, {propertyWrapperTypeString}.RefVisitMethod a, IPropertyVisitor v) => a(ref container.m_{propertyType.PropertyName}, v)";
            }

            return(new PropertyWrapperAccessors()
            {
                ValueGetter = $"/* GET */ ({containerAsAParemeterType} container) => container.{propertyAccessorName}",
                ValueSetter = propertySetter,
                RefGetter = propertyRefGetter
            });
        }
Example #6
0
        private static string GeneratePropertyWrapperBackingVariable(
            string propertyWrapperTypeName,
            PropertyTypeNode.TypeTag containerTypeTag,
            PropertyTypeNode propertyType)
        {
            var accessModifiers = AccessModifiers.Static | AccessModifiers.Readonly;

            if (containerTypeTag == PropertyTypeNode.TypeTag.Class)
            {
                accessModifiers |= (propertyType.IsPublicProperty ? AccessModifiers.Public : AccessModifiers.Protected);
            }
            else
            {
                accessModifiers |= AccessModifiers.Private;
            }
            var modifiers = string.Join(" ", ModifiersToStrings(accessModifiers));

            var propertyWrapperVariableName = GetPropertyWrapperVariableName(propertyType);

            return($@"{modifiers} {propertyWrapperTypeName} {propertyWrapperVariableName};");
        }
Example #7
0
        private static string GeneratePropertyWrapperInitializer(
            string propertyName,
            string containerName,
            PropertyTypeNode.TypeTag containerTypeTag,
            string propertyWrapperTypeString,
            bool isReadonlyProperty,
            string propertyAccessorName,
            string propertyTypeString,
            PropertyTypeNode.TypeTag propertyTypeTag
            )
        {
            List <string> initializerParams = new List <string>();

            var containerAsAParemeterType =
                containerTypeTag.HasFlag(PropertyTypeNode.TypeTag.Struct) ? $"ref {containerName}" : $"{containerName}";

            initializerParams.Add($"nameof({propertyName})");

            initializerParams.Add($"/* GET */ ({containerAsAParemeterType} container) => container.{propertyAccessorName}");

            var propertySetter = "/* SET */ null";

            if (!PropertyTypeNode.IsCompositeType(propertyTypeTag) && !isReadonlyProperty)
            {
                propertySetter = $"/* SET */ ({containerAsAParemeterType} container, {propertyTypeString} value) => container.{propertyAccessorName} = value";
            }
            initializerParams.Add(propertySetter);

            if (propertyTypeTag == PropertyTypeNode.TypeTag.Struct)
            {
                initializerParams.Add(
                    $"/* REF */ ({containerAsAParemeterType} container, {propertyWrapperTypeString}.RefVisitMethod a, IPropertyVisitor v) => a(ref container.m_{propertyName}, v)"
                    );
            }

            string parameters = string.Join(", ", initializerParams);

            return($@"new { propertyWrapperTypeString }( {parameters} )");
        }
Example #8
0
        private static void GenerateClassPropertiesForPropertyAccessor(
            PropertyTypeNode.TypeTag containerTypeTag,
            PropertyTypeNode propertyType,
            Scope code
            )
        {
            var containerAsAParamTokens = new List <string> {
            };

            if (containerTypeTag.HasFlag(PropertyTypeNode.TypeTag.Struct))
            {
                containerAsAParamTokens.Add("ref");
            }
            containerAsAParamTokens.Add("this");

            var getSetValueCallContainerParam = string.Join(" ", containerAsAParamTokens);

            var propertyWrapperVariableName = GetPropertyWrapperVariableName(propertyType);

            var propertyTypeString = TypeDeclarationStringForProperty(propertyType);

            var isCompositeType = PropertyTypeNode.IsCompositeType(propertyType.Tag);

            var modifiers = string.Join(" ", ModifiersToStrings(AccessModifiers.Public));

            code.AddLine($"{modifiers} {propertyTypeString} {propertyType.PropertyName}");

            {
                code.AddLine("{");
                var accessorScope = new Scope(code);
                accessorScope.AddLine($"get {{ return {propertyWrapperVariableName}.GetValue({getSetValueCallContainerParam}); }}");
                if (!isCompositeType)
                {
                    accessorScope.AddLine($"set {{ {propertyWrapperVariableName}.SetValue({getSetValueCallContainerParam}, value); }}");
                }
                code.AddLine("}");
            }
        }
Example #9
0
        private static string GetPropertyWrapperTypeFor(
            string containerName,
            PropertyTypeNode.TypeTag containerTypeTag,
            PropertyTypeNode propertyType)
        {
            // TODO warning we rely on type definitions here
            var propertyWrapperTypeStringPrefix = "";

            if (containerTypeTag.HasFlag(PropertyTypeNode.TypeTag.Struct))
            {
                propertyWrapperTypeStringPrefix = "Struct";
            }

            switch (propertyType.Tag)
            {
            case PropertyTypeNode.TypeTag.Struct:
                return($"{propertyWrapperTypeStringPrefix}MutableContainerProperty<{containerName}, {propertyType.TypeName}>");

            case PropertyTypeNode.TypeTag.Class:
                return($"{propertyWrapperTypeStringPrefix}ContainerProperty<{containerName}, {propertyType.TypeName}>");

            case PropertyTypeNode.TypeTag.Enum:
                return($"{propertyWrapperTypeStringPrefix}EnumProperty<{containerName}, {propertyType.TypeName}>");

            case PropertyTypeNode.TypeTag.Array:
            case PropertyTypeNode.TypeTag.List:
            {
                var t = TypeStringFromEnumerableProperty(propertyType);
                return($"{propertyWrapperTypeStringPrefix}ListProperty<{containerName}, {t}, {propertyType.Of.TypeName}>");
            }

            default:
                break;
            }

            return($"{propertyWrapperTypeStringPrefix}Property<{containerName}, {propertyType.TypeName}>");
        }
Example #10
0
        public void GenerateProperty(
            string containerName,
            PropertyTypeNode.TypeTag containerTypeTag,
            PropertyTypeNode propertyType,
            Scope code)
        {
            // Public C# Property & backing field

            GenerateClassPropertiesForPropertyAccessor(containerTypeTag, propertyType, code);

            var propertyWrapperTypeName = GetPropertyWrapperTypeFor(
                containerName,
                containerTypeTag,
                propertyType);

            code.AddLine(GeneratePropertyWrapperBackingVariable(
                             propertyWrapperTypeName, containerTypeTag, propertyType));

            // Backing field if any

            var propertyAccessorName = string.Empty;
            var backingField         = GeneratePropertyBackingField(
                propertyType.PropertyName,
                propertyType,
                out propertyAccessorName
                );

            if (!string.IsNullOrEmpty(backingField))
            {
                // If we have a class we delegate init to constructor otherwise we default construct here

                var initializer = GenerateInitializerFromProperty(containerTypeTag, propertyType);

                var initializerFragment = backingField;

                if (!string.IsNullOrEmpty(initializer) && !propertyType.DontInitializeBackingField)
                {
                    initializerFragment += $" = {initializer}";
                }

                initializerFragment += ";";

                code.AddLine(initializerFragment);
            }

            //      -> Add constructor initializer fragments for later stage for that property

            var propertyTypeString          = TypeDeclarationStringForProperty(propertyType);
            var propertyWrapperVariableName = GetPropertyWrapperVariableName(propertyType);

            {
                var initializer = GeneratePropertyWrapperInitializers(
                    propertyType,
                    containerName,
                    containerTypeTag,
                    propertyWrapperTypeName,
                    propertyAccessorName,
                    propertyTypeString,
                    code);

                AddStaticConstructorInStageFragment(
                    ConstructorStage.PropertyInitializationStage,
                    new CSharpGenerationFragmentContext()
                {
                    Scope    = code,
                    Fragment = $"{propertyWrapperVariableName} = {initializer};"
                });
            }

            PropertyBagItemNames.Add(propertyWrapperVariableName);
        }
Example #11
0
        private void GenerateProperty(
            string containerName,
            PropertyTypeNode.TypeTag containerTypeTag,
            PropertyTypeNode propertyType,
            StringBuffer gen)
        {
            var propertyWrapperVariableName = $"s_{propertyType.Name}Property";
            var propertyTypeString          = TypeDeclarationStringForProperty(propertyType);

            if (!string.IsNullOrWhiteSpace(propertyType.IsInheritedFrom))
            {
                // Just add a propertybag member
                PropertyBagItemNames.Add(
                    $"new InheritedProperty<{propertyType.IsInheritedFrom}, {containerName}, {propertyTypeString}>({propertyWrapperVariableName})"
                    );
                return;
            }

            var propertyWrapperTypeName = GetPropertyWrapperTypeFor(
                containerName,
                containerTypeTag,
                propertyType);

            bool isCompositeType = PropertyTypeNode.IsCompositeType(propertyType.Tag);

            // Backing field if any

            var propertyAccessorName = string.Empty;
            var backingField         = GeneratePropertyBackingField(
                propertyType.Name,
                propertyType,
                out propertyAccessorName
                );

            if (!string.IsNullOrEmpty(backingField))
            {
                // If we have a class we delegate init to constructor otherwise we default construct here

                var initializer = GenerateInitializerFromProperty(propertyType);

                gen.Append(' ', Style.Space * 1);
                gen.Append(backingField);

                if (!string.IsNullOrEmpty(initializer))
                {
                    if (containerTypeTag == PropertyTypeNode.TypeTag.Struct)
                    {
                        gen.Append($"= {initializer}");
                    }
                    else
                    {
                        // Add an initializer for that
                        ConstructorInitializerFragments.Add(() => $"{propertyAccessorName} = {initializer};");
                    }
                }

                gen.Append($";{Environment.NewLine}");
            }

            // Public C# Property

            // @TODO extract as a method

            var containerAsAParamTokens = new List <String> {
            };

            if (containerTypeTag.HasFlag(PropertyTypeNode.TypeTag.Struct))
            {
                containerAsAParamTokens.Add("ref");
            }
            containerAsAParamTokens.Add("this");

            var getSetValueCallContainerParam = string.Join(" ", containerAsAParamTokens);

            gen.Append(' ', Style.Space * 1);
            var modifiers = string.Join(" ", ModifiersToStrings(AccessModifiers.Public));

            gen.Append($@"{modifiers} {propertyTypeString} {propertyType.Name}
        {{
            get {{ return {propertyWrapperVariableName}.GetValue({getSetValueCallContainerParam}); }}
            set {{ {
                    (isCompositeType ? string.Empty : $"{propertyWrapperVariableName}.SetValue({getSetValueCallContainerParam}, value);")
                } }}