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)} )"); }
public override void AddStringFragment() { if (!string.IsNullOrEmpty(Fragment)) { Scope.AddLine(Fragment); } }
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("}"); } }
private void GeneratePropertyContainerFor( PropertyTypeNode c, Func <string, CSharpGenerationCache.CodeInfo> dependancyLookupFunc, StringBuffer gen) { var containerName = c.TypeName; var containerTypeTag = c.Tag; var baseClass = string.IsNullOrEmpty(c.OverrideDefaultBaseClass) ? "IPropertyContainer" : c.OverrideDefaultBaseClass; var rootScope = new Scope(); var shouldGeneratePRopertyContainerImplementation = !c.NoDefaultImplementation; using (var d = new PropertyContainerDataTypeDecorator(c, rootScope.Code, new List <string> { baseClass })) using (var scope = new Scope(rootScope)) { if (shouldGeneratePRopertyContainerImplementation) { if (c.Properties.Count != 0) { foreach (var propertyType in c.Properties) { GenerateProperty( containerName, containerTypeTag, propertyType, scope ); scope.AddLine(""); } scope.AddLine(""); } GenerateUserHooksFor(c, scope); // Add inherited properties if it applies var propertyBagElementNames = PropertyBagItemNames; if (!string.IsNullOrEmpty(c.OverrideDefaultBaseClass) && dependancyLookupFunc != null) { var cachedContainer = dependancyLookupFunc(c.OverrideDefaultBaseClass); if (cachedContainer != null) { propertyBagElementNames = PropertyBagItemNames.Select(n => n).ToList(); propertyBagElementNames.AddRange(cachedContainer.GeneratedPropertyFieldNames); } } GeneratePropertyBag( c, propertyBagElementNames, scope); GenerateConstructorFor(c, scope.Code); GenerateStaticConstructorFor(c, scope.Code); // @TODO Cleanup // Recurse to collect nested container definitions foreach (var nestedContainer in c.NestedContainers) { if (nestedContainer == null) { continue; } var g = new CSharpContainerGenerator() { DoGenerateNamespace = false }; g.GeneratePropertyContainer(nestedContainer, dependancyLookupFunc); if (!string.IsNullOrEmpty(g.Code.ToString())) { scope.AddLine(string.Empty); scope.AddLine(string.Empty); scope.AddLine(g.Code.ToString()); scope.AddLine(string.Empty); scope.AddLine(string.Empty); } } scope.AddLine("public IVersionStorage VersionStorage => DefaultVersionStorage.Instance;"); scope.AddLine(Environment.NewLine); } } gen.Append(rootScope.Code); }
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); }