/// <summary>
        /// Gets a collection of <see cref="DataSourceWrapperInfo"/> objects for all of the views defined within the specified root directory
        /// as well as all of the component templates which are currently registered with the Ultraviolet context.
        /// </summary>
        /// <param name="state">The expression compiler's current state.</param>
        /// <param name="root">The root directory to search for views.</param>
        /// <returns>A collection of <see cref="DataSourceWrapperInfo"/> instances which represent the views and templates which were found.</returns>
        public static IEnumerable <DataSourceWrapperInfo> GetDataSourceWrapperInfos(IExpressionCompilerState state, String root)
        {
            var viewDefinitions = RecursivelySearchForViews(root, root);
            var viewModelInfos  = RetrieveDataSourceWrapperInfos(state, viewDefinitions);

            var templateDefinitions = RetrieveTemplateDefinitions(state);
            var templateModelInfos  = RetrieveDataSourceWrapperInfos(state, templateDefinitions);

            return(Enumerable.Union(viewModelInfos, templateModelInfos));
        }
        /// <summary>
        /// Attempts to find the dependency or attached property with the specified name.
        /// </summary>
        /// <param name="state">The expression compiler's current state.</param>
        /// <param name="name">The name of the dependency or attached property to retrieve.</param>
        /// <param name="ownerType">The type that references the dependency or attached property.</param>
        /// <returns>The <see cref="DependencyProperty"/> referred to by the specified name, or <see langword="null"/> if there is no such dependency property.</returns>
        private static DependencyProperty FindDependencyOrAttachedPropertyByName(IExpressionCompilerState state, String name, Type ownerType)
        {
            if (ExpressionUtil.IsAttachedProperty(name, out var container, out var property))
            {
                if (!state.GetKnownType(container, out var containerType))
                    return null;

                return DependencyProperty.FindByName(property, containerType);
            }
            return DependencyProperty.FindByName(name, ownerType);
        }
Esempio n. 3
0
        /// <summary>
        /// Given a targeted binding expression (in the form "foo->bar"), this method extracts the target name, target type, and expression text.
        /// </summary>
        private Boolean GetExpressionTargetInfo(IExpressionCompilerState state, DataSourceWrapperInfo dataSourceWrapperInfo,
                                                XObject source, ref String expText, out String expTarget, out Type expTargetType)
        {
            const string TargetExpressionDelimiter = "->";

            var expOriginal = expText;

            var delimiterIndex = expText.IndexOf(TargetExpressionDelimiter);

            if (delimiterIndex >= 0)
            {
                var expPartTarget = expText.Substring(0, delimiterIndex);
                var expPartText   = expText.Substring(delimiterIndex + TargetExpressionDelimiter.Length);

                var matchCandidates = (from element in dataSourceWrapperInfo.DataSourceDefinition.Definition.Descendants()
                                       where (String)element.Attribute("Name") == expPartTarget
                                       select element).ToList();

                if (matchCandidates.Count == 0)
                {
                    throw new BindingExpressionCompilationErrorException(source, dataSourceWrapperInfo.DataSourceDefinition.DefinitionPath,
                                                                         CompilerStrings.ExpressionTargetIsNotFound.Format(expPartTarget));
                }

                if (matchCandidates.Count > 1)
                {
                    throw new BindingExpressionCompilationErrorException(source, dataSourceWrapperInfo.DataSourceDefinition.DefinitionPath,
                                                                         CompilerStrings.ExpressionTargetIsAmbiguous.Format(expPartTarget));
                }

                var match     = matchCandidates.Single();
                var matchName = match.Name.LocalName;

                expText       = expPartText;
                expTargetType = UvmlTypeAnalysis.GetPlaceholderType(dataSourceWrapperInfo.DataSourceType, matchName);

                if (expTargetType == null && !state.GetKnownType(matchName, out expTargetType))
                {
                    throw new BindingExpressionCompilationErrorException(source, dataSourceWrapperInfo.DataSourceDefinition.DefinitionPath,
                                                                         CompilerStrings.ExpressionTargetIsUnrecognizedType.Format(expOriginal, matchName));
                }

                expTarget = String.Format("__UPF_FindName<{0}>(\"{1}\").", CSharpLanguage.GetCSharpTypeName(expTargetType), expPartTarget);

                return(true);
            }

            expTarget     = default(String);
            expTargetType = dataSourceWrapperInfo.DataSourceType;

            return(false);
        }
        /// <summary>
        /// Gets a collection of <see cref="DataSourceDefinition"/> instances for any component templates which
        /// are currently registered with the Ultraviolet Presentation Foundation.
        /// </summary>
        /// <returns>A collection of <see cref="DataSourceDefinition"/> instances which represent UPF component template definitions.</returns>
        private static IEnumerable<DataSourceDefinition> RetrieveTemplateDefinitions(IExpressionCompilerState state)
        {
            if (state.ComponentTemplateManager == null)
                return Enumerable.Empty<DataSourceDefinition>();

            var templateDefs = from template in state.ComponentTemplateManager
                               select DataSourceDefinition.FromComponentTemplate(template.Key, template.Value.Root.Element("View"));
            var templateDefsList = templateDefs.ToList();

            foreach (var templateDef in templateDefsList)
                UvmlLoader.AddUvmlAnnotations(templateDef.DataSourceWrapperName, templateDef.Definition);

            return templateDefsList;
        }
Esempio n. 5
0
        /// <summary>
        /// Installs the specified NuGet package into the current working directory.
        /// </summary>
        /// <param name="state">The compiler's current state.</param>
        /// <param name="packageID">The identifier of the package to install.</param>
        /// <param name="version">The version of the package to install, or <see langword="null"/> to install the newest version.</param>
        /// <returns><see langword="true"/> if the package was installed successfully; otherwise, <see langword="false"/>.</returns>
        public static Boolean InstallNuGetPackage(IExpressionCompilerState state, String packageID, String version = null)
        {
            Contract.Require(state, nameof(state));
            Contract.RequireNotEmpty(packageID, nameof(packageID));

            if (!IsNuGetAvailable())
            {
                throw new PlatformNotSupportedException();
            }

            Debug.Write("NuGet: Installing package " + packageID + "... ");

            var dir = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
            var exe = Path.Combine(dir, "nuget.exe");

            var args = String.IsNullOrEmpty(version) ? $"install {packageID} -Source nuget.org" : $"install {packageID} -Source nuget.org -Version {version}";
            var proc = new Process()
            {
                StartInfo = new ProcessStartInfo()
                {
                    FileName               = exe,
                    Arguments              = args,
                    UseShellExecute        = false,
                    CreateNoWindow         = true,
                    RedirectStandardOutput = true,
                    WorkingDirectory       = state.GetWorkingDirectory()
                }
            };

            proc.Start();
            var exited = proc.WaitForExit((Int32)TimeSpan.FromMinutes(5).TotalSeconds);

            Debug.WriteLine("done.");

            return(exited && proc.ExitCode == 0);
        }
        /// <summary>
        /// Creates an instance of <see cref="DataSourceWrapperInfo"/> for each of the specified data source definitions.
        /// </summary>
        /// <param name="state">The expression compiler's current state.</param>
        /// <param name="dataSourceDefinitions">The collection of <see cref="DataSourceDefinition"/> objects for which to create <see cref="DataSourceWrapperInfo"/> instances.</param>
        /// <returns>A collection containing the <see cref="DataSourceWrapperInfo"/> instances which were created.</returns>
        private static IEnumerable <DataSourceWrapperInfo> RetrieveDataSourceWrapperInfos(IExpressionCompilerState state, IEnumerable <DataSourceDefinition> dataSourceDefinitions)
        {
            var dataSourceWrapperInfos = new ConcurrentBag <DataSourceWrapperInfo>();

            Parallel.ForEach(dataSourceDefinitions, viewDefinition =>
            {
                var dataSourceWrapperInfo = GetDataSourceWrapperInfo(state, viewDefinition);
                if (dataSourceWrapperInfo == null)
                {
                    return;
                }

                dataSourceWrapperInfos.Add(dataSourceWrapperInfo);
            });

            return(dataSourceWrapperInfos);
        }
        /// <summary>
        /// Creates a new instance of <see cref="DataSourceWrapperInfo"/> that represents the specified data source wrapper.
        /// </summary>
        /// <param name="state">The expression compiler's current state.</param>
        /// <param name="dataSourceDefinition">The data source definition for which to retrieve data source wrapper info.</param>
        /// <returns>The <see cref="DataSourceWrapperInfo"/> that was created to represent the specified data source.</returns>
        public static DataSourceWrapperInfo GetDataSourceWrapperInfo(IExpressionCompilerState state, DataSourceDefinition dataSourceDefinition)
        {
            var dataSourceWrappedType = dataSourceDefinition.TemplatedControl;

            if (dataSourceWrappedType == null)
            {
                var definedDataSourceTypeAttr = dataSourceDefinition.Definition.Attribute("ViewModelType");
                var definedDataSourceTypeName = (String)definedDataSourceTypeAttr;
                if (definedDataSourceTypeName == null)
                {
                    return(null);
                }

                var typeNameCommaIx = definedDataSourceTypeName.IndexOf(',');
                if (typeNameCommaIx < 0)
                {
                    throw new BindingExpressionCompilationErrorException(definedDataSourceTypeAttr, dataSourceDefinition.DefinitionPath,
                                                                         CompilerStrings.ViewModelTypeIsNotFullyQualified.Format(definedDataSourceTypeName));
                }

                var definedDataSourceType = Type.GetType(definedDataSourceTypeName);
                if (definedDataSourceType == null)
                {
                    throw new BindingExpressionCompilationErrorException(definedDataSourceTypeAttr, dataSourceDefinition.DefinitionPath,
                                                                         PresentationStrings.ViewModelTypeNotFound.Format(definedDataSourceTypeName));
                }

                dataSourceWrappedType = definedDataSourceType;
            }

            var dataSourceWrapperName        = dataSourceDefinition.DataSourceWrapperName;
            var dataSourceWrapperExpressions = new List <BindingExpressionInfo>();

            foreach (var element in dataSourceDefinition.Definition.Elements())
            {
                FindBindingExpressionsInDataSource(state,
                                                   dataSourceDefinition, dataSourceWrappedType, element, dataSourceWrapperExpressions);
            }

            dataSourceWrapperExpressions = CollapseDataSourceExpressions(dataSourceWrapperExpressions);

            var dataSourceReferences = new List <String>();
            var dataSourceImports    = new List <String>();

            var xmlRoot       = dataSourceDefinition.Definition.Parent;
            var xmlDirectives = xmlRoot.Elements("Directive");

            foreach (var xmlDirective in xmlDirectives)
            {
                var xmlDirectiveType = (String)xmlDirective.Attribute("Type");
                if (String.IsNullOrEmpty(xmlDirectiveType))
                {
                    throw new BindingExpressionCompilationErrorException(xmlDirective, dataSourceDefinition.DefinitionPath,
                                                                         CompilerStrings.ViewDirectiveMustHaveType);
                }

                var xmlDirectiveTypeName = xmlDirectiveType.ToLowerInvariant();
                var xmlDirectiveValue    = xmlDirective.Value.Trim();
                switch (xmlDirectiveTypeName)
                {
                case "import":
                {
                    if (String.IsNullOrEmpty(xmlDirectiveValue))
                    {
                        throw new BindingExpressionCompilationErrorException(xmlDirective, dataSourceDefinition.DefinitionPath,
                                                                             CompilerStrings.ViewDirectiveHasInvalidValue);
                    }
                    dataSourceImports.Add(xmlDirective.Value.Trim());
                }
                break;

                case "reference":
                {
                    if (String.IsNullOrEmpty(xmlDirectiveValue))
                    {
                        throw new BindingExpressionCompilationErrorException(xmlDirective, dataSourceDefinition.DefinitionPath,
                                                                             CompilerStrings.ViewDirectiveHasInvalidValue);
                    }
                    dataSourceReferences.Add(xmlDirective.Value.Trim());
                }
                break;

                default:
                    throw new BindingExpressionCompilationErrorException(xmlDirective, dataSourceDefinition.DefinitionPath,
                                                                         CompilerStrings.ViewDirectiveNotRecognized.Format(xmlDirectiveTypeName));
                }
            }

            var frameworkTemplates = new Dictionary <String, XElement>();

            FindFrameworkTemplateElements(dataSourceDefinition.Definition, frameworkTemplates);

            var frameworkTemplateWrapperDefs = frameworkTemplates.Select(x =>
                                                                         DataSourceDefinition.FromView(dataSourceDefinition.DataSourceWrapperNamespace, x.Key, dataSourceDefinition.DefinitionPath, x.Value)).ToList();

            var frameworkTemplateWrapperInfos = frameworkTemplateWrapperDefs.Select(definition =>
                                                                                    GetDataSourceWrapperInfoForFrameworkTemplate(state, dataSourceReferences, dataSourceImports, definition)).ToList();

            return(new DataSourceWrapperInfo()
            {
                References = dataSourceReferences,
                Imports = dataSourceImports,
                DataSourceDefinition = dataSourceDefinition,
                DataSourcePath = dataSourceDefinition.DefinitionPath,
                DataSourceType = dataSourceWrappedType,
                DataSourceWrapperName = dataSourceWrapperName,
                Expressions = dataSourceWrapperExpressions,
                DependentWrapperInfos = frameworkTemplateWrapperInfos
            });
        }
        /// <summary>
        /// Searches the specified XML element tree for binding expressions and adds them to the specified collection.
        /// </summary>
        /// <param name="state">The expression compiler's current state.</param>
        /// <param name="dataSourceDefinition">The data source definition for the data source which is being compiled.</param>
        /// <param name="dataSourceWrappedType">The type for which a data source wrapper is being compiled.</param>
        /// <param name="element">The root of the XML element tree to search.</param>
        /// <param name="expressions">The list to populate with any binding expressions that are found.</param>
        private static void FindBindingExpressionsInDataSource(IExpressionCompilerState state, DataSourceDefinition dataSourceDefinition,
                                                               Type dataSourceWrappedType, XElement element, List <BindingExpressionInfo> expressions)
        {
            var templateAnnotation = element.Annotation <FrameworkTemplateNameAnnotation>();

            if (templateAnnotation != null)
            {
                return;
            }

            var elementName = element.Name.LocalName;
            var elementType = UvmlTypeAnalysis.GetPlaceholderType(dataSourceWrappedType, elementName);

            if (elementType != null || state.GetKnownType(elementName, out elementType))
            {
                var attrs = Enumerable.Union(
                    element.Attributes().Select(x =>
                                                new { Object = (XObject)x, Name = x.Name.LocalName, Value = x.Value }),
                    element.Elements().Where(x => x.Name.LocalName.StartsWith(elementName + ".")).Select(x =>
                                                                                                         new { Object = (XObject)x, Name = x.Name.LocalName, Value = x.Value }));

                foreach (var attr in attrs)
                {
                    var attrValue = attr.Value;
                    if (!BindingExpressions.IsBindingExpression(attrValue))
                    {
                        continue;
                    }

                    var dprop = FindDependencyOrAttachedPropertyByName(state, attr.Name, elementType);
                    if (dprop == null)
                    {
                        throw new BindingExpressionCompilationErrorException(attr.Object, dataSourceDefinition.DefinitionPath,
                                                                             CompilerStrings.OnlyDependencyPropertiesCanBeBound.Format(attr.Name));
                    }

                    var expText = BindingExpressions.GetBindingMemberPathPart(attrValue);
                    var expProp = GetBindablePropertyOnDataSource(dataSourceWrappedType, expText);
                    var expType = expProp?.PropertyType ?? dprop.PropertyType;
                    if (typeof(DataTemplate).IsAssignableFrom(expType))
                    {
                        continue;
                    }

                    expressions.Add(new BindingExpressionInfo(attr.Object, attrValue, expType)
                    {
                        GenerateGetter = true
                    });
                }

                if (element.Nodes().Count() == 1)
                {
                    var singleChild = element.Nodes().Single();
                    if (singleChild.NodeType == XmlNodeType.Text)
                    {
                        var elementValue = ((XText)singleChild).Value;
                        if (BindingExpressions.IsBindingExpression(elementValue))
                        {
                            String defaultProperty;
                            if (!state.GetElementDefaultProperty(elementType, out defaultProperty) || defaultProperty == null)
                            {
                                throw new BindingExpressionCompilationErrorException(singleChild, dataSourceDefinition.DefinitionPath,
                                                                                     CompilerStrings.ElementDoesNotHaveDefaultProperty.Format(elementType.Name));
                            }

                            var dprop = FindDependencyOrAttachedPropertyByName(state, defaultProperty, elementType);
                            if (dprop == null)
                            {
                                throw new BindingExpressionCompilationErrorException(singleChild, dataSourceDefinition.DefinitionPath,
                                                                                     CompilerStrings.OnlyDependencyPropertiesCanBeBound.Format(defaultProperty));
                            }

                            var expText = BindingExpressions.GetBindingMemberPathPart(elementValue);
                            var expProp = GetBindablePropertyOnDataSource(dataSourceWrappedType, expText);

                            expressions.Add(new BindingExpressionInfo(singleChild,
                                                                      elementValue, expProp?.PropertyType ?? dprop.PropertyType)
                            {
                                GenerateGetter = true
                            });
                        }
                    }
                }
            }

            var children = element.Elements();

            foreach (var child in children)
            {
                FindBindingExpressionsInDataSource(state, dataSourceDefinition,
                                                   dataSourceWrappedType, child, expressions);
            }
        }
        /// <summary>
        /// Creates a new <see cref="DataSourceWrapperInfo"/> instance which represents a particular framework template.
        /// </summary>
        public static DataSourceWrapperInfo GetDataSourceWrapperInfoForFrameworkTemplate(IExpressionCompilerState state,
                                                                                         IEnumerable <String> references, IEnumerable <String> imports, DataSourceDefinition definition)
        {
            var dataSourceWrappedTypeAttr = definition.Definition.Attribute("ViewModelType");

            if (dataSourceWrappedTypeAttr == null)
            {
                throw new BindingExpressionCompilationErrorException(definition.Definition, definition.DefinitionPath,
                                                                     PresentationStrings.TemplateMustSpecifyViewModelType);
            }

            var dataSourceWrappedType = Type.GetType(dataSourceWrappedTypeAttr.Value, false);

            if (dataSourceWrappedType == null)
            {
                throw new BindingExpressionCompilationErrorException(dataSourceWrappedTypeAttr, definition.DefinitionPath,
                                                                     PresentationStrings.ViewModelTypeNotFound.Format(dataSourceWrappedTypeAttr.Value));
            }

            var dataSourceDefinition  = definition;
            var dataSourceWrapperName = definition.DataSourceWrapperName;

            var expressions = new List <BindingExpressionInfo>();

            foreach (var element in dataSourceDefinition.Definition.Elements())
            {
                FindBindingExpressionsInDataSource(state,
                                                   dataSourceDefinition, dataSourceWrappedType, element, expressions);
            }
            expressions = CollapseDataSourceExpressions(expressions);

            return(new DataSourceWrapperInfo()
            {
                References = references,
                Imports = imports,
                DataSourceDefinition = dataSourceDefinition,
                DataSourceType = dataSourceWrappedType,
                DataSourceWrapperName = dataSourceWrapperName,
                Expressions = expressions
            });
        }
Esempio n. 10
0
        /// <summary>
        /// Writes a property which wraps a binding expression.
        /// </summary>
        /// <param name="state">The expression compiler's current state.</param>
        /// <param name="dataSourceWrapperInfo">A <see cref="DataSourceWrapperInfo"/> describing the data source for which to write an expression property.</param>
        /// <param name="expressionInfo">The binding expression for which to write a property.</param>
        /// <param name="id">The expression's identifier within the view model.</param>
        public void WriteExpressionProperty(IExpressionCompilerState state, DataSourceWrapperInfo dataSourceWrapperInfo, BindingExpressionInfo expressionInfo, Int32 id)
        {
            var isDependencyProperty       = false;
            var isSimpleDependencyProperty = false;

            var expText         = BindingExpressions.GetBindingMemberPathPart(expressionInfo.Expression);
            var expTarget       = default(String);
            var expTargetType   = dataSourceWrapperInfo.DataSourceType;
            var expFormatString = BindingExpressions.GetBindingFormatStringPart(expressionInfo.Expression);

            var targeted = GetExpressionTargetInfo(state, dataSourceWrapperInfo,
                                                   expressionInfo.Source, ref expText, out expTarget, out expTargetType);

            var dprop      = DependencyProperty.FindByName(expText, expTargetType);
            var dpropField = default(FieldInfo);

            if (dprop != null)
            {
                isDependencyProperty = true;

                dpropField =
                    (from prop in dprop.OwnerType.GetFields(BindingFlags.Public | BindingFlags.Static)
                     where
                     prop.FieldType == typeof(DependencyProperty) &&
                     prop.GetValue(null) == dprop
                     select prop).SingleOrDefault();

                if (dpropField == null)
                {
                    throw new BindingExpressionCompilationErrorException(expressionInfo.Source, dataSourceWrapperInfo.DataSourceDefinition.DefinitionPath,
                                                                         PresentationStrings.CannotFindDependencyPropertyField.Format(dprop.OwnerType.Name, dprop.Name));
                }

                if (String.IsNullOrEmpty(expFormatString) && !targeted)
                {
                    isSimpleDependencyProperty = true;
                }
            }

            WriteLine("[{0}(@\"{1}\", SimpleDependencyPropertyOwner = {2}, SimpleDependencyPropertyName = {3})]", typeof(CompiledBindingExpressionAttribute).FullName, expressionInfo.Expression.Replace("\"", "\"\""),
                      isSimpleDependencyProperty ? "typeof(" + CSharpLanguage.GetCSharpTypeName(dprop.OwnerType) + ")" : "null",
                      isSimpleDependencyProperty ? "\"" + dprop.Name + "\"" : "null");

            WriteLine("public {0} __UPF_Expression{1}", CSharpLanguage.GetCSharpTypeName(expressionInfo.Type), id);
            WriteLine("{");

            if (expressionInfo.GenerateGetter)
            {
                expressionInfo.GetterLineStart = LineCount;

                var getexp = default(String);
                if (isDependencyProperty)
                {
                    getexp = String.Format("{0}GetValue<{1}>({2}.{3})", expTarget,
                                           CSharpLanguage.GetCSharpTypeName(dprop.PropertyType),
                                           CSharpLanguage.GetCSharpTypeName(dprop.OwnerType), dpropField.Name);
                }
                else
                {
                    getexp = String.Format("{0}{1}", expTarget, expText);
                }

                var hasFormatString = !String.IsNullOrEmpty(expFormatString);
                expFormatString = hasFormatString ? String.Format("\"{{0:{0}}}\"", expFormatString) : "null";

                if (IsStringType(expressionInfo.Type) || (expressionInfo.Type == typeof(Object) && hasFormatString))
                {
                    WriteLine("get");
                    WriteLine("{");
                    WriteLine("var value = {0};", getexp);
                    WriteLine("return ({0})__UPF_ConvertToString(value, {1});", CSharpLanguage.GetCSharpTypeName(expressionInfo.Type), expFormatString);
                    WriteLine("}");
                }
                else
                {
                    WriteLine("get {{ return ({0})({1}); }}", CSharpLanguage.GetCSharpTypeName(expressionInfo.Type), getexp);
                }

                expressionInfo.GetterLineEnd = LineCount - 1;
            }

            if (dprop != null && dprop.IsReadOnly)
            {
                expressionInfo.GenerateSetter = false;
            }

            if (expressionInfo.GenerateSetter)
            {
                var targetTypeName      = expressionInfo.CS0266TargetType;
                var targetTypeSpecified = !String.IsNullOrEmpty(targetTypeName);

                expressionInfo.SetterLineStart = LineCount;
                if (isDependencyProperty)
                {
                    if (IsStringType(expressionInfo.Type))
                    {
                        WriteLine("set");
                        WriteLine("{");
                        WriteLine("var current = {0}GetValue<{1}>({2}.{3});",
                                  expTarget, CSharpLanguage.GetCSharpTypeName(dprop.PropertyType), CSharpLanguage.GetCSharpTypeName(dprop.OwnerType), dpropField.Name);
                        WriteLine("{0}SetValue<{1}>({2}.{3}, __UPF_ConvertFromString(value, current));",
                                  expTarget, CSharpLanguage.GetCSharpTypeName(dprop.PropertyType), CSharpLanguage.GetCSharpTypeName(dprop.OwnerType), dpropField.Name);
                        WriteLine("}");
                    }
                    else
                    {
                        if (expressionInfo.NullableFixup)
                        {
                            WriteLine(targetTypeSpecified ? "set {{ {0}SetValue<{1}>({2}.{3}, ({4})(value ?? default({1}))); }}" : "set {{ {0}SetValue<{1}>({2}.{3}, value ?? default({1})); }}",
                                      expTarget,
                                      CSharpLanguage.GetCSharpTypeName(dprop.PropertyType),
                                      CSharpLanguage.GetCSharpTypeName(dprop.OwnerType),
                                      dpropField.Name, targetTypeName);
                        }
                        else
                        {
                            WriteLine(targetTypeSpecified ? "set {{ {0}SetValue<{1}>({2}.{3}, ({4})(value)); }}" : "set {{ {0}SetValue<{1}>({2}.{3}, value); }}",
                                      expTarget,
                                      CSharpLanguage.GetCSharpTypeName(dprop.PropertyType),
                                      CSharpLanguage.GetCSharpTypeName(dprop.OwnerType),
                                      dpropField.Name, targetTypeName);
                        }
                    }
                }
                else
                {
                    if (IsStringType(expressionInfo.Type))
                    {
                        WriteLine("set");
                        WriteLine("{");
                        WriteLine("var current = {0}{1};", expTarget, expText);
                        WriteLine("{0}{1} = __UPF_ConvertFromString(value, current);", expTarget, expText);
                        WriteLine("}");
                    }
                    else
                    {
                        if (expressionInfo.NullableFixup)
                        {
                            WriteLine(targetTypeSpecified ? "set {{ ({0}{1}) = ({3})(value ?? default({2})); }}" : "set {{ ({0}{1}) = value ?? default({2}); }}",
                                      expTarget, expText, CSharpLanguage.GetCSharpTypeName(Nullable.GetUnderlyingType(expressionInfo.Type)), targetTypeName);
                        }
                        else
                        {
                            WriteLine(targetTypeSpecified ? "set {{ ({0}{1}) = ({2})(value); }}" : "set {{ ({0}{1}) = value; }}",
                                      expTarget, expText, targetTypeName);
                        }
                    }
                }

                expressionInfo.SetterLineEnd = LineCount - 1;
            }

            WriteLine("}");
            WriteLine();

            if (expressionInfo.GenerateGetter)
            {
                WriteLine("public static readonly DataBindingGetter<{0}> __Get__UPF_Expression{1} = new DataBindingGetter<{0}>(vm => (({2})vm).__UPF_Expression{1});",
                          CSharpLanguage.GetCSharpTypeName(expressionInfo.Type), id, dataSourceWrapperInfo.DataSourceWrapperName);
                WriteLine();
            }

            if (expressionInfo.GenerateSetter)
            {
                WriteLine("public static readonly DataBindingSetter<{0}> __Set__UPF_Expression{1} = new DataBindingSetter<{0}>((vm, value) => (({2})vm).__UPF_Expression{1} = value);",
                          CSharpLanguage.GetCSharpTypeName(expressionInfo.Type), id, dataSourceWrapperInfo.DataSourceWrapperName);
                WriteLine();
            }
        }