public void EmitSetDotvvmProperty(string controlName, DotvvmProperty property, ExpressionSyntax value)
        {
            UsedAssemblies.Add(property.DeclaringType.Assembly);
            UsedAssemblies.Add(property.PropertyType.Assembly);

            if (property.IsVirtual)
            {
                EmitSetProperty(controlName, property.PropertyInfo.Name, EmitValue(value));
            }
            else
            {
                CurrentStatements.Add(
                    SyntaxFactory.ExpressionStatement(
                        SyntaxFactory.InvocationExpression(
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.ParseName(property.DescriptorFullName),
                                SyntaxFactory.IdentifierName("SetValue")
                                ),
                            SyntaxFactory.ArgumentList(
                                SyntaxFactory.SeparatedList(
                                    new[] {
                    SyntaxFactory.Argument(SyntaxFactory.IdentifierName(controlName)),
                    SyntaxFactory.Argument(value)
                }
                                    )
                                )
                            )
                        )
                    );
            }
        }
 /// <summary>
 /// Emits the add directive.
 /// </summary>
 public void EmitAddDirective(string controlName, string name, string value)
 {
     CurrentStatements.Add(
         SyntaxFactory.ExpressionStatement(
             SyntaxFactory.AssignmentExpression(
                 SyntaxKind.SimpleAssignmentExpression,
                 SyntaxFactory.ElementAccessExpression(
                     SyntaxFactory.MemberAccessExpression(
                         SyntaxKind.SimpleMemberAccessExpression,
                         SyntaxFactory.IdentifierName(controlName),
                         SyntaxFactory.IdentifierName("Directives")
                         ),
                     SyntaxFactory.BracketedArgumentList(
                         SyntaxFactory.SeparatedList(
                             new[]
     {
         SyntaxFactory.Argument(EmitStringLiteral(name))
     }
                             )
                         )
                     ),
                 EmitStringLiteral(value)
                 )
             )
         );
 }
 /// <summary>
 /// Emits the add HTML attribute.
 /// </summary>
 public void EmitAddToDictionary(string controlName, string propertyName, string key, ExpressionSyntax valueSyntax)
 {
     CurrentStatements.Add(
         SyntaxFactory.ExpressionStatement(
             SyntaxFactory.AssignmentExpression(
                 SyntaxKind.SimpleAssignmentExpression,
                 SyntaxFactory.ElementAccessExpression(
                     SyntaxFactory.MemberAccessExpression(
                         SyntaxKind.SimpleMemberAccessExpression,
                         SyntaxFactory.IdentifierName(controlName),
                         SyntaxFactory.IdentifierName(propertyName)
                         ),
                     SyntaxFactory.BracketedArgumentList(
                         SyntaxFactory.SeparatedList(
                             new[]
     {
         SyntaxFactory.Argument(EmitStringLiteral(key))
     }
                             )
                         )
                     ),
                 valueSyntax
                 )
             )
         );
 }
        /// <summary>
        /// Emits the set attached property.
        /// </summary>
        public void EmitSetAttachedProperty(string controlName, DotvvmProperty property, object value)
        {
            UsedAssemblies.Add(property.DeclaringType.Assembly);
            UsedAssemblies.Add(property.PropertyType.Assembly);

            CurrentStatements.Add(
                SyntaxFactory.ExpressionStatement(
                    SyntaxFactory.InvocationExpression(
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            SyntaxFactory.IdentifierName(controlName),
                            SyntaxFactory.IdentifierName("SetValue")
                            ),
                        SyntaxFactory.ArgumentList(
                            SyntaxFactory.SeparatedList(
                                new[] {
                SyntaxFactory.Argument(
                    SyntaxFactory.MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        ParseTypeName(property.DeclaringType),
                        SyntaxFactory.IdentifierName(property.Name + "Property")
                        )
                    ),
                SyntaxFactory.Argument(
                    EmitValue(value)
                    )
            }
                                )
                            )
                        )
                    )
                );
        }
 /// <summary>
 /// Emits the set property statement.
 /// </summary>
 public void EmitSetProperty(string controlName, string propertyName, ExpressionSyntax valueSyntax)
 {
     CurrentStatements.Add(
         SyntaxFactory.ExpressionStatement(
             SyntaxFactory.AssignmentExpression(
                 SyntaxKind.SimpleAssignmentExpression,
                 SyntaxFactory.MemberAccessExpression(
                     SyntaxKind.SimpleMemberAccessExpression,
                     SyntaxFactory.IdentifierName(controlName),
                     SyntaxFactory.IdentifierName(propertyName)
                     ),
                 valueSyntax
                 )
             )
         );
 }
        public string EmitCreateVariable(ExpressionSyntax expression)
        {
            var name = "c" + CurrentControlIndex;

            CurrentControlIndex++;

            CurrentStatements.Add(
                SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var")).WithVariables(
                        SyntaxFactory.VariableDeclarator(name).WithInitializer(
                            SyntaxFactory.EqualsValueClause(expression)
                            )
                        )
                    )
                );
            return(name);
        }
 /// <summary>
 /// Emits the set binding statement.
 /// </summary>
 public void EmitSetBinding(string controlName, string propertyName, ExpressionSyntax binding)
 {
     CurrentStatements.Add(
         SyntaxFactory.ExpressionStatement(
             SyntaxFactory.InvocationExpression(
                 SyntaxFactory.MemberAccessExpression(
                     SyntaxKind.SimpleMemberAccessExpression,
                     SyntaxFactory.IdentifierName(controlName),
                     SyntaxFactory.IdentifierName("SetBinding")
                     ),
                 SyntaxFactory.ArgumentList(
                     SyntaxFactory.SeparatedList(new[] {
         SyntaxFactory.Argument(SyntaxFactory.ParseName(propertyName)),
         SyntaxFactory.Argument(binding)
     })
                     )
                 )
             )
         );
 }
        public void EmitSetDotvvmProperty(string controlName, DotvvmProperty property, ExpressionSyntax value)
        {
            UseType(property.DeclaringType);
            UseType(property.PropertyType);

            if (property.IsVirtual)
            {
                var gProperty = property as GroupedDotvvmProperty;
                if (gProperty != null && gProperty.PropertyGroup.PropertyGroupMode == PropertyGroupMode.ValueCollection)
                {
                    EmitAddToDictionary(controlName, property.CastTo <GroupedDotvvmProperty>().PropertyGroup.Name, gProperty.GroupMemberName, value);
                }
                else
                {
                    EmitSetProperty(controlName, property.PropertyInfo.Name, value);
                }
            }
            else
            {
                CurrentStatements.Add(
                    SyntaxFactory.ExpressionStatement(
                        SyntaxFactory.InvocationExpression(
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                CreateDotvvmPropertyIdentifier(property),
                                SyntaxFactory.IdentifierName("SetValue")
                                ),
                            SyntaxFactory.ArgumentList(
                                SyntaxFactory.SeparatedList(
                                    new[] {
                    SyntaxFactory.Argument(SyntaxFactory.IdentifierName(controlName)),
                    SyntaxFactory.Argument(value)
                }
                                    )
                                )
                            )
                        )
                    );
            }
        }
        /// <summary>
        /// Emits the code that adds the specified value as a child item in the collection.
        /// </summary>
        public void EmitAddCollectionItem(string controlName, string variableName, string collectionPropertyName = "Children")
        {
            ExpressionSyntax collectionExpression;

            if (string.IsNullOrEmpty(collectionPropertyName))
            {
                collectionExpression = SyntaxFactory.IdentifierName(controlName);
            }
            else
            {
                collectionExpression = SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    SyntaxFactory.IdentifierName(controlName),
                    SyntaxFactory.IdentifierName(collectionPropertyName)
                    );
            }

            CurrentStatements.Add(
                SyntaxFactory.ExpressionStatement(
                    SyntaxFactory.InvocationExpression(
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            collectionExpression,
                            SyntaxFactory.IdentifierName("Add")
                            )
                        ).WithArgumentList(
                        SyntaxFactory.ArgumentList(
                            SyntaxFactory.SeparatedList(
                                new[]
            {
                SyntaxFactory.Argument(SyntaxFactory.IdentifierName(variableName))
            }
                                )
                            )
                        )
                    )
                );
        }
 /// <summary>
 /// Emits the return clause.
 /// </summary>
 public void EmitReturnClause(string variableName)
 {
     CurrentStatements.Add(SyntaxFactory.ReturnStatement(SyntaxFactory.IdentifierName(variableName)));
 }
        public string EmitEnsureCollectionInitialized(string parentName, DotvvmProperty property)
        {
            UsedAssemblies.Add(property.PropertyType.Assembly);

            if (property.IsVirtual)
            {
                StatementSyntax initializer;
                if (property.PropertyInfo.SetMethod != null)
                {
                    initializer = SyntaxFactory.ExpressionStatement(
                        SyntaxFactory.AssignmentExpression(
                            SyntaxKind.SimpleAssignmentExpression,
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.IdentifierName(parentName),
                                SyntaxFactory.IdentifierName(property.Name)
                                ),
                            SyntaxFactory.ObjectCreationExpression(ParseTypeName(property.PropertyType))
                            .WithArgumentList(
                                SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new ArgumentSyntax[] { }))
                                )
                            )
                        );
                }
                else
                {
                    initializer = SyntaxFactory.ThrowStatement(
                        CreateObjectExpression(typeof(InvalidOperationException),
                                               new[] { EmitStringLiteral($"Property '{ property.FullName }' can't be used as control collection since it is not initialized and does not have setter available for automatic initialization") }
                                               )
                        );
                }
                CurrentStatements.Add(
                    SyntaxFactory.IfStatement(
                        SyntaxFactory.BinaryExpression(
                            SyntaxKind.EqualsExpression,
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.IdentifierName(parentName),
                                SyntaxFactory.IdentifierName(property.Name)
                                ),
                            SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression)
                            ),
                        initializer
                        )
                    );

                return(EmitCreateVariable(
                           SyntaxFactory.MemberAccessExpression(
                               SyntaxKind.SimpleMemberAccessExpression,
                               SyntaxFactory.IdentifierName(parentName),
                               SyntaxFactory.IdentifierName(property.Name)
                               )
                           ));
            }
            else
            {
                CurrentStatements.Add(
                    SyntaxFactory.IfStatement(
                        SyntaxFactory.BinaryExpression(
                            SyntaxKind.EqualsExpression,
                            SyntaxFactory.InvocationExpression(
                                SyntaxFactory.MemberAccessExpression(
                                    SyntaxKind.SimpleMemberAccessExpression,
                                    SyntaxFactory.IdentifierName(parentName),
                                    SyntaxFactory.IdentifierName("GetValue")
                                    ),
                                SyntaxFactory.ArgumentList(
                                    SyntaxFactory.SeparatedList(new[]
                {
                    SyntaxFactory.Argument(SyntaxFactory.ParseName(property.DescriptorFullName))
                })
                                    )
                                ),
                            SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression)
                            ),
                        SyntaxFactory.ExpressionStatement(
                            SyntaxFactory.InvocationExpression(
                                SyntaxFactory.MemberAccessExpression(
                                    SyntaxKind.SimpleMemberAccessExpression,
                                    SyntaxFactory.IdentifierName(parentName),
                                    SyntaxFactory.IdentifierName("SetValue")
                                    ),
                                SyntaxFactory.ArgumentList(
                                    SyntaxFactory.SeparatedList(new[]
                {
                    SyntaxFactory.Argument(SyntaxFactory.ParseName(property.DescriptorFullName)),
                    SyntaxFactory.Argument(
                        SyntaxFactory.ObjectCreationExpression(ParseTypeName(property.PropertyType))
                        .WithArgumentList(
                            SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new ArgumentSyntax[] { }))
                            )
                        )
                })
                                    )
                                )
                            )
                        )
                    );
                return(EmitCreateVariable(
                           SyntaxFactory.CastExpression(
                               ParseTypeName(property.PropertyType),
                               SyntaxFactory.InvocationExpression(
                                   SyntaxFactory.MemberAccessExpression(
                                       SyntaxKind.SimpleMemberAccessExpression,
                                       SyntaxFactory.IdentifierName(parentName),
                                       SyntaxFactory.IdentifierName("GetValue")
                                       ),
                                   SyntaxFactory.ArgumentList(
                                       SyntaxFactory.SeparatedList(new[]
                {
                    SyntaxFactory.Argument(SyntaxFactory.ParseName(property.DescriptorFullName))
                })
                                       )
                                   )
                               )
                           ));
            }
        }
        /// <summary>
        /// Emits the control builder invocation.
        /// </summary>
        public string EmitInvokeControlBuilder(Type controlType, string virtualPath)
        {
            UsedAssemblies.Add(controlType.Assembly);

            var builderName = "c" + CurrentControlIndex + "_builder";
            var untypedName = "c" + CurrentControlIndex + "_untyped";
            var name        = "c" + CurrentControlIndex;

            CurrentControlIndex++;

            CurrentStatements.Add(
                SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var")).WithVariables(
                        SyntaxFactory.VariableDeclarator(builderName).WithInitializer(
                            SyntaxFactory.EqualsValueClause(
                                SyntaxFactory.InvocationExpression(
                                    SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                         SyntaxFactory.IdentifierName(ControlBuilderFactoryParameterName),
                                                                         SyntaxFactory.IdentifierName(GetControlBuilderFunctionName)
                                                                         ),
                                    SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] {
                SyntaxFactory.Argument(EmitStringLiteral(virtualPath))
            }))
                                    )
                                )
                            )
                        )
                    )
                );
            CurrentStatements.Add(
                SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var")).WithVariables(
                        SyntaxFactory.VariableDeclarator(untypedName).WithInitializer(
                            SyntaxFactory.EqualsValueClause(
                                SyntaxFactory.InvocationExpression(
                                    SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                         SyntaxFactory.IdentifierName(builderName),
                                                                         SyntaxFactory.IdentifierName(BuildControlFunctionName)
                                                                         ),
                                    SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] {
                SyntaxFactory.Argument(SyntaxFactory.IdentifierName(ControlBuilderFactoryParameterName))
            }))
                                    )
                                )
                            )
                        )
                    )
                );
            CurrentStatements.Add(
                SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var")).WithVariables(
                        SyntaxFactory.VariableDeclarator(name).WithInitializer(
                            SyntaxFactory.EqualsValueClause(
                                SyntaxFactory.CastExpression(ParseTypeName(controlType),
                                                             SyntaxFactory.IdentifierName(untypedName)
                                                             )
                                )
                            )
                        )
                    )
                );

            return(name);
        }