Esempio n. 1
0
        public static bool TryConvertMarkupExtension(XamlIlAstTransformationContext context,
                                                     IXamlIlAstValueNode node, out XamlIlMarkupExtensionNode o)
        {
            o = null;
            var nodeType   = node.Type.GetClrType();
            var candidates = GetMarkupExtensionProvideValueAlternatives(context, nodeType).ToList();
            var so         = context.Configuration.WellKnownTypes.Object;
            var sp         = context.Configuration.TypeMappings.ServiceProvider;

            // Try non-object variant first and variants without IServiceProvider argument first

            var provideValue = candidates.FirstOrDefault(m => m.Parameters.Count == 0 && !m.ReturnType.Equals(so))
                               ?? candidates.FirstOrDefault(m => m.Parameters.Count == 0)
                               ?? candidates.FirstOrDefault(m =>
                                                            m.Parameters.Count == 1 && m.Parameters[0].Equals(sp) && !m.ReturnType.Equals(so))
                               ?? candidates.FirstOrDefault(m => m.Parameters.Count == 1 && m.Parameters[0].Equals(sp));

            if (provideValue == null)
            {
                if (node.Type.IsMarkupExtension)
                {
                    throw new XamlIlParseException(
                              $"{node.Type.GetClrType().GetFqn()} was resolved as markup extension, but doesn't have a matching ProvideValue/ProvideTypedValue method",
                              node.Type);
                }

                return(false);
            }
            o = new XamlIlMarkupExtensionNode(node, provideValue, node);
            return(true);
        }
Esempio n. 2
0
File: Clr.cs Progetto: cm4ker/XamlIl
 public XamlIlValueWithManipulationNode(IXamlIlLineInfo lineInfo,
                                        IXamlIlAstValueNode value,
                                        IXamlIlAstManipulationNode manipulation) : base(lineInfo, value)
 {
     Value        = value;
     Manipulation = manipulation;
 }
Esempio n. 3
0
 public XamlIlLoadMethodDelegateNode(IXamlIlLineInfo lineInfo, IXamlIlAstValueNode value,
                                     IXamlIlType delegateType, IXamlIlMethod method) : base(lineInfo, value)
 {
     DelegateType = delegateType;
     Method       = method;
     Type         = new XamlIlAstClrTypeReference(value, DelegateType);
 }
Esempio n. 4
0
File: Clr.cs Progetto: cm4ker/XamlIl
 public XamlIlPropertyAssignmentNode(IXamlIlLineInfo lineInfo,
                                     IXamlIlProperty property, IXamlIlAstValueNode value)
     : base(lineInfo)
 {
     Property = property;
     Value    = value;
 }
        public static bool TryConvertMarkupExtension(XamlIlAstTransformationContext context,
                                                     IXamlIlAstValueNode node, IXamlIlProperty prop, out XamlIlMarkupExtensionNode o)
        {
            o = null;
            var nodeType   = node.Type.GetClrType();
            var candidates = nodeType.Methods.Where(m => m.Name == "ProvideValue" && m.IsPublic && !m.IsStatic)
                             .ToList();
            var so = context.Configuration.WellKnownTypes.Object;
            var sp = context.Configuration.TypeMappings.ServiceProvider;

            // Try non-object variant first and variants without IServiceProvider argument first

            var provideValue = candidates.FirstOrDefault(m => m.Parameters.Count == 0 && !m.ReturnType.Equals(so))
                               ?? candidates.FirstOrDefault(m => m.Parameters.Count == 0)
                               ?? candidates.FirstOrDefault(m =>
                                                            m.Parameters.Count == 1 && m.Parameters[0].Equals(sp) && !m.ReturnType.Equals(so))
                               ?? candidates.FirstOrDefault(m => m.Parameters.Count == 1 && m.Parameters[0].Equals(sp));

            if (provideValue == null)
            {
                return(false);
            }
            o = new XamlIlMarkupExtensionNode(node, prop, provideValue, node, null);
            return(true);
        }
Esempio n. 6
0
        public static bool CustomValueConverter(XamlIlAstTransformationContext context,
                                                IXamlIlAstValueNode node, IXamlIlType type, out IXamlIlAstValueNode result)
        {
            if (type.FullName == "System.TimeSpan" &&
                node is XamlIlAstTextNode tn &&
                !tn.Text.Contains(":"))
            {
                var seconds = double.Parse(tn.Text, CultureInfo.InvariantCulture);
                result = new XamlIlStaticOrTargetedReturnMethodCallNode(tn,
                                                                        type.FindMethod("FromSeconds", type, false, context.Configuration.WellKnownTypes.Double),
                                                                        new[]
                {
                    new XamlIlConstantNode(tn, context.Configuration.WellKnownTypes.Double, seconds)
                });
                return(true);
            }

            if (type.FullName == "Avalonia.AvaloniaProperty")
            {
                var scope = context.ParentNodes().OfType <AvaloniaXamlIlTargetTypeMetadataNode>().FirstOrDefault();
                if (scope == null)
                {
                    throw new XamlIlLoadException("Unable to find the parent scope for AvaloniaProperty lookup", node);
                }
                if (!(node is XamlIlAstTextNode text))
                {
                    throw new XamlIlLoadException("Property should be a text node", node);
                }
                result = XamlIlAvaloniaPropertyHelper.CreateNode(context, text.Text, scope.TargetType, text);
                return(true);
            }

            result = null;
            return(false);
        }
Esempio n. 7
0
 public XamlIlAstLocalInitializationNodeEmitter(IXamlIlLineInfo lineInfo,
                                                IXamlIlAstValueNode value,
                                                XamlIlAstCompilerLocalNode local) : base(lineInfo, value)
 {
     Value = value;
     Local = local;
 }
        static IXamlIlAstValueNode FindAndRemoveKey(IXamlIlAstValueNode value)
        {
            IXamlIlAstValueNode keyNode = null;

            bool IsKeyDirective(object node) => node is XamlIlAstXmlDirective d &&
            d.Namespace == XamlNamespaces.Xaml2006 &&
            d.Name == "Key";

            void ProcessDirective(object d)
            {
                var directive = (XamlIlAstXmlDirective)d;

                if (directive.Values.Count != 1)
                {
                    throw new XamlIlParseException("Invalid number of arguments for x:Key directive",
                                                   directive);
                }
                keyNode = directive.Values[0];
            }

            void ProcessDirectiveCandidateList(IList nodes)
            {
                var d = nodes.OfType <object>().FirstOrDefault(IsKeyDirective);

                if (d != null)
                {
                    ProcessDirective(d);
                    nodes.Remove(d);
                }
            }

            IXamlIlAstManipulationNode VisitManipulationNode(IXamlIlAstManipulationNode man)
            {
                if (IsKeyDirective(man))
                {
                    ProcessDirective(man);
                    return(new XamlIlManipulationGroupNode(man));
                }
                if (man is XamlIlManipulationGroupNode grp)
                {
                    ProcessDirectiveCandidateList(grp.Children);
                }
                if (man is XamlIlObjectInitializationNode init)
                {
                    init.Manipulation = VisitManipulationNode(init.Manipulation);
                }
                return(man);
            }

            if (value is XamlIlAstObjectNode astObject)
            {
                ProcessDirectiveCandidateList(astObject.Children);
            }
            else if (value is XamlIlValueWithManipulationNode vman)
            {
                vman.Manipulation = VisitManipulationNode(vman.Manipulation);
            }

            return(keyNode);
        }
Esempio n. 9
0
 public XamlIlMarkupExtensionNode(IXamlIlLineInfo lineInfo, IXamlIlMethod provideValue,
                                  IXamlIlAstValueNode value) : base(lineInfo)
 {
     ProvideValue = provideValue;
     Value        = value;
     Type         = new XamlIlAstClrTypeReference(this, ProvideValue.ReturnType, false);
 }
 public XamlIlPropertyEqualsSelector(XamlIlSelectorNode previous,
                                     IXamlIlProperty property,
                                     IXamlIlAstValueNode value)
     : base(previous)
 {
     Property = property;
     Value    = value;
 }
Esempio n. 11
0
File: Clr.cs Progetto: cm4ker/XamlIl
 public XamlIlMarkupExtensionNode(IXamlIlLineInfo lineInfo, IXamlIlProperty property, IXamlIlMethod provideValue,
                                  IXamlIlAstValueNode value, IXamlIlWrappedMethod manipulation) : base(lineInfo)
 {
     Property     = property;
     ProvideValue = provideValue;
     Value        = value;
     Manipulation = manipulation;
 }
Esempio n. 12
0
 public XamlIlAstXamlPropertyValueNode(IXamlIlLineInfo lineInfo,
                                       IXamlIlAstPropertyReference property, IXamlIlAstValueNode value) : base(lineInfo)
 {
     Property = property;
     Values   = new List <IXamlIlAstValueNode> {
         value
     };
 }
Esempio n. 13
0
        public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node)
        {
            if (node is XamlIlPropertyAssignmentNode pa &&
                pa.Property.Name == "Name" &&
                pa.Property.DeclaringType.FullName == "Avalonia.StyledElement")
            {
                if (context.ParentNodes().FirstOrDefault() is XamlIlManipulationGroupNode mg &&
                    mg.Children.OfType <AvaloniaNameScopeRegistrationXamlIlNode>().Any())
                {
                    return(node);
                }

                IXamlIlAstValueNode value = null;
                for (var c = 0; c < pa.Values.Count; c++)
                {
                    if (pa.Values[c].Type.GetClrType().Equals(context.Configuration.WellKnownTypes.String))
                    {
                        value = pa.Values[c];
                        if (!(value is XamlIlAstTextNode))
                        {
                            var local = new XamlIlAstCompilerLocalNode(value);
                            // Wrap original in local initialization
                            pa.Values[c] = new XamlIlAstLocalInitializationNodeEmitter(value, value, local);
                            // Use local
                            value = local;
                        }

                        break;
                    }
                }

                if (value != null)
                {
                    return new XamlIlManipulationGroupNode(pa)
                           {
                               Children =
                               {
                                   pa,
                                   new AvaloniaNameScopeRegistrationXamlIlNode(value, context.GetAvaloniaTypes())
                               }
                           }
                }
                ;
            }

            if (!context.ParentNodes().Any() &&
                node is XamlIlValueWithManipulationNode mnode)
            {
                mnode.Manipulation = new XamlIlManipulationGroupNode(mnode,
                                                                     new[]
                {
                    mnode.Manipulation,
                    new HandleRootObjectScopeNode(mnode, context.GetAvaloniaTypes())
                });
            }
            return(node);
        }
Esempio n. 14
0
File: Clr.cs Progetto: cm4ker/XamlIl
        public XamlIlDeferredContentNode(IXamlIlAstValueNode value,
                                         XamlIlTransformerConfiguration config) : base(value)
        {
            Value = value;
            var funcType = config.TypeSystem.GetType("System.Func`2")
                           .MakeGenericType(config.TypeMappings.ServiceProvider, config.WellKnownTypes.Object);

            Type = new XamlIlAstClrTypeReference(value, funcType);
        }
Esempio n. 15
0
        public static bool TryGetCorrectlyTypedValue(XamlIlAstTransformationContext context,
                                                     IXamlIlAstValueNode node, IXamlIlType type, out IXamlIlAstValueNode rv)
        {
            if (type.IsAssignableFrom(node.Type.GetClrType()))
            {
                rv = node;
                return(true);
            }

            return(TryConvertValue(context, node, type, null, out rv));
        }
Esempio n. 16
0
        void CompileBuild(IXamlIlAstValueNode rootInstance, Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType,
                          IXamlIlEmitter codeGen, XamlIlContext context, IXamlIlMethod compiledPopulate)
        {
            var needContextLocal = !(rootInstance is XamlIlAstNewClrObjectNode newObj && newObj.Arguments.Count == 0);
            var emitContext      = InitCodeGen(createSubType, codeGen, context, needContextLocal);


            var rv = codeGen.DefineLocal(rootInstance.Type.GetClrType());

            emitContext.Emit(rootInstance, codeGen, rootInstance.Type.GetClrType());
            codeGen
            .Emit(OpCodes.Stloc, rv)
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Ldloc, rv)
            .Emit(OpCodes.Call, compiledPopulate)
            .Emit(OpCodes.Ldloc, rv)
            .Emit(OpCodes.Ret);
        }
Esempio n. 17
0
        public static bool TryCallAdd(XamlIlAstTransformationContext context,
                                      IXamlIlProperty targetProperty, IXamlIlType targetPropertyType, IXamlIlAstValueNode value, out IXamlIlAstManipulationNode rv)
        {
            var so = context.Configuration.WellKnownTypes.Object;

            rv = null;
            IXamlIlWrappedMethod FindAdderImpl(IXamlIlType targetType, IXamlIlType valueType, IXamlIlType keyType = null)
            {
                var candidates = targetType.FindMethods(m =>
                                                        !m.IsStatic && m.IsPublic &&
                                                        (m.Name == "Add" || m.Name.EndsWith(".Add"))).ToList();

                bool CheckArg(IXamlIlType argType, bool allowObj)
                {
                    if (allowObj && argType.Equals(so))
                    {
                        return(true);
                    }
                    if (!allowObj && !argType.Equals(so) && argType.IsAssignableFrom(valueType))
                    {
                        return(true);
                    }
                    return(false);
                }

                foreach (var allowObj in new[] { false, true })
                {
                    foreach (var m in candidates)
                    {
                        if (keyType == null && m.Parameters.Count == 1 &&
                            CheckArg(m.Parameters[0], allowObj))
                        {
                            return(new XamlIlWrappedMethod(m));
                        }
                        if (keyType != null && m.Parameters.Count == 2 &&
                            m.Parameters[0].IsAssignableFrom(keyType) &&
                            CheckArg(m.Parameters[1], allowObj))
                        {
                            return(new XamlIlWrappedMethod(m));
                        }
                    }
                }

                return(null);
            }

            IXamlIlWrappedMethod FindAdderWithCast(IXamlIlType originalType, IXamlIlType newTargetType, IXamlIlType valueType)
            {
                var m = FindAdderImpl(newTargetType, valueType);

                if (m == null)
                {
                    return(null);
                }
                return(new XamlIlWrappedMethodWithCasts(m, new[] { originalType, m.ParametersWithThis[1] }));
            }

            IXamlIlWrappedMethod FindAdder(IXamlIlType valueType, IXamlIlType keyType = null)
            {
                if (keyType == null)
                {
                    if (targetPropertyType.Equals(context.Configuration.WellKnownTypes.IEnumerable))
                    {
                        return(FindAdderWithCast(targetPropertyType, context.Configuration.WellKnownTypes.IList,
                                                 valueType));
                    }
                    if (targetPropertyType.GenericTypeDefinition?.Equals(context.Configuration.WellKnownTypes
                                                                         .IEnumerableT) == true)
                    {
                        return(FindAdderWithCast(
                                   targetPropertyType,
                                   context.Configuration.WellKnownTypes.IListOfT
                                   .MakeGenericType(targetPropertyType.GenericArguments[0]), valueType));
                    }
                }
                return(FindAdderImpl(targetPropertyType, valueType, keyType));
            }

            if (TryConvertMarkupExtension(context, value, targetProperty, out var ext))
            {
                var adder = FindAdder(ext.ProvideValue.ReturnType);
                if (adder != null)
                {
                    ext.Manipulation = adder;
                    rv = ext;
                    return(true);
                }
            }
            else
            {
                var vtype = value.Type.GetClrType();
                IXamlIlAstValueNode keyNode = null;

                bool IsKeyDirective(object node) => node is XamlIlAstXmlDirective d &&
                d.Namespace == XamlNamespaces.Xaml2006 &&
                d.Name == "Key";

                void ProcessDirective(object d)
                {
                    var directive = (XamlIlAstXmlDirective)d;

                    if (directive.Values.Count != 1)
                    {
                        throw new XamlIlParseException("Invalid number of arguments for x:Key directive",
                                                       directive);
                    }
                    keyNode = directive.Values[0];
                }

                void ProcessDirectiveCandidateList(IList nodes)
                {
                    var d = nodes.OfType <object>().FirstOrDefault(IsKeyDirective);

                    if (d != null)
                    {
                        ProcessDirective(d);
                        nodes.Remove(d);
                    }
                }

                IXamlIlAstManipulationNode VisitManipulationNode(IXamlIlAstManipulationNode man)
                {
                    if (IsKeyDirective(man))
                    {
                        ProcessDirective(man);
                        return(new XamlIlManipulationGroupNode(man));
                    }
                    if (man is XamlIlManipulationGroupNode grp)
                    {
                        ProcessDirectiveCandidateList(grp.Children);
                    }
                    if (man is XamlIlObjectInitializationNode init)
                    {
                        init.Manipulation = VisitManipulationNode(init.Manipulation);
                    }
                    return(man);
                }

                if (value is XamlIlAstObjectNode astObject)
                {
                    ProcessDirectiveCandidateList(astObject.Children);
                }
                else if (value is XamlIlValueWithManipulationNode vman)
                {
                    vman.Manipulation = VisitManipulationNode(vman.Manipulation);
                }


                var adder = FindAdder(vtype, keyNode?.Type.GetClrType());
                if (adder != null)
                {
                    var args = new List <IXamlIlAstValueNode>();
                    if (keyNode != null)
                    {
                        args.Add(keyNode);
                    }
                    args.Add(value);

                    rv = new XamlIlNoReturnMethodCallNode(value, adder, args);
                    if (targetProperty != null)
                    {
                        rv = new XamlIlPropertyValueManipulationNode(value, targetProperty, rv);
                    }
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 18
0
 public XamlIlAstCompilerLocalNode(IXamlIlAstValueNode value) : this(value, value.Type.GetClrTypeReference())
 {
 }
Esempio n. 19
0
 public XamlIlAstNeedsParentStackValueNode(IXamlIlLineInfo lineInfo, IXamlIlAstValueNode value) : base(lineInfo, value)
 {
 }
Esempio n. 20
0
 public XamlIlAstImperativeValueManipulation(IXamlIlLineInfo lineInfo,
                                             IXamlIlAstValueNode value, IXamlIlAstManipulationNode manipulation) : base(lineInfo)
 {
     Value        = value;
     Manipulation = manipulation;
 }
Esempio n. 21
0
 public XamlIlAstRuntimeCastNode(IXamlIlLineInfo lineInfo, IXamlIlAstValueNode value, IXamlIlAstTypeReference castTo) : base(lineInfo)
 {
     Value = value;
     Type  = castTo;
 }
Esempio n. 22
0
        public static bool TryCallAdd(XamlIlAstTransformationContext context,
                                      IXamlIlProperty targetProperty, IXamlIlType targetPropertyType, IXamlIlAstValueNode value, out IXamlIlAstManipulationNode rv)
        {
            if (TryConvertMarkupExtension(context, value, targetProperty, out var ext))
            {
                var adder = new[] { ext.ProvideValue.ReturnType, context.Configuration.WellKnownTypes.Object }
                .Select(argType => targetPropertyType.FindMethod(m =>
                                                                 !m.IsStatic && m.IsPublic &&
                                                                 (m.Name == "Add" || m.Name.EndsWith(".Add")) &&
                                                                 m.Parameters.Count == 1 &&
                                                                 m.Parameters[0].Equals(argType)))
                .FirstOrDefault(m => m != null);
                if (adder != null)
                {
                    ext.Manipulation = adder;
                    rv = ext;
                    return(true);
                }
            }

            if (context.Configuration.TryCallAdd(targetPropertyType, value, out var nret))
            {
                if (targetProperty != null)
                {
                    rv = new XamlIlPropertyValueManipulationNode(value, targetProperty, nret);
                }
                else
                {
                    rv = nret;
                }
                return(true);
            }

            rv = null;
            return(false);
        }
 public ScopeRegistrationNode(IXamlIlAstValueNode value) : base(value)
 {
     Value = value;
 }
Esempio n. 24
0
File: Clr.cs Progetto: cm4ker/XamlIl
 protected XamlIlValueWithSideEffectNodeBase(IXamlIlLineInfo lineInfo, IXamlIlAstValueNode value) : base(lineInfo)
 {
     Value = value;
 }
Esempio n. 25
0
 public XamlIlValueNodeWithBeginInit(IXamlIlAstValueNode value) : base(value, value)
 {
 }
Esempio n. 26
0
File: Clr.cs Progetto: cm4ker/XamlIl
 public override void VisitChildren(Visitor visitor)
 {
     Value = (IXamlIlAstValueNode)Value.Visit(visitor);
 }
Esempio n. 27
0
 public override void VisitChildren(IXamlIlAstVisitor visitor)
 => Name = (IXamlIlAstValueNode)Name.Visit(visitor);
Esempio n. 28
0
 public AvaloniaNameScopeRegistrationXamlIlNode(IXamlIlAstValueNode name, AvaloniaXamlIlWellKnownTypes types) : base(name)
 {
     _types = types;
     Name   = name;
 }
Esempio n. 29
0
File: Clr.cs Progetto: cm4ker/XamlIl
 public XamlIlToArrayNode(IXamlIlLineInfo lineInfo, IXamlIlAstTypeReference arrayType,
                          IXamlIlAstValueNode value) : base(lineInfo)
 {
     Type  = arrayType;
     Value = value;
 }
Esempio n. 30
0
        public static bool TryConvertValue(XamlIlAstTransformationContext context,
                                           IXamlIlAstValueNode node, IXamlIlType type, XamlIlAstClrProperty propertyContext,
                                           out IXamlIlAstValueNode rv)
        {
            rv = null;
            var cfg = context.Configuration;

            // Since we are doing a conversion anyway, it makes sense to check for the underlying nullable type
            if (type.GenericTypeDefinition?.Equals(cfg.WellKnownTypes.NullableT) == true)
            {
                type = type.GenericArguments[0];
            }


            if (cfg.CustomValueConverter?.Invoke(context, node, type, out rv) == true)
            {
                return(true);
            }

            var nodeType = node.Type.GetClrType();

            // Implicit type converters
            if (!nodeType.Equals(cfg.WellKnownTypes.String))
            {
                return(false);
            }

            if (node is XamlIlAstTextNode tn)
            {
                if (type.IsEnum)
                {
                    if (TypeSystemHelpers.TryGetEnumValueNode(type, tn.Text, tn, out var enumConstantNode))
                    {
                        rv = enumConstantNode;
                        return(true);
                    }
                }

                // Well known types
                if (TypeSystemHelpers.ParseConstantIfTypeAllows(tn.Text, type, tn, out var constantNode))
                {
                    rv = constantNode;
                    return(true);
                }

                if (type.FullName == "System.Type")
                {
                    var resolvedType = XamlIlTypeReferenceResolver.ResolveType(context, tn.Text, false, tn, true);
                    rv = new XamlIlTypeExtensionNode(tn, resolvedType, type);
                    return(true);
                }

                if (cfg.WellKnownTypes.Delegate.IsAssignableFrom(type))
                {
                    var invoke   = type.FindMethod(m => m.Name == "Invoke");
                    var rootType = context.RootObject.Type.GetClrType();
                    var handler  =
                        rootType.FindMethod(tn.Text, invoke.ReturnType, false, invoke.Parameters.ToArray());
                    if (handler != null)
                    {
                        rv = new XamlIlLoadMethodDelegateNode(tn, context.RootObject, type, handler);
                        return(true);
                    }
                }
            }

            IXamlIlAstValueNode CreateInvariantCulture() =>
            new XamlIlStaticOrTargetedReturnMethodCallNode(node,
                                                           cfg.WellKnownTypes.CultureInfo.Methods.First(x =>
                                                                                                        x.IsPublic && x.IsStatic && x.Name == "get_InvariantCulture"), null);

            var candidates = type.Methods.Where(m => m.Name == "Parse" &&
                                                m.ReturnType.Equals(type) &&
                                                m.Parameters.Count > 0 &&
                                                m.Parameters[0].Equals(cfg.WellKnownTypes.String)).ToList();

            // Types with parse method
            var parser = candidates.FirstOrDefault(m =>
                                                   m.Parameters.Count == 2 &&
                                                   (
                                                       m.Parameters[1].Equals(cfg.WellKnownTypes.CultureInfo) ||
                                                       m.Parameters[1].Equals(cfg.WellKnownTypes.IFormatProvider)
                                                   )
                                                   )
                         ?? candidates.FirstOrDefault(m => m.Parameters.Count == 1);

            if (parser != null)
            {
                var args = new List <IXamlIlAstValueNode> {
                    node
                };
                if (parser.Parameters.Count == 2)
                {
                    args.Add(CreateInvariantCulture());
                }

                rv = new XamlIlStaticOrTargetedReturnMethodCallNode(node, parser, args);
                return(true);
            }

            if (cfg.TypeMappings.TypeDescriptorContext != null)
            {
                IXamlIlType converterType = null;
                if (propertyContext?.TypeConverters.TryGetValue(type, out converterType) != true)
                {
                    var typeConverterAttribute =
                        cfg.GetCustomAttribute(type, cfg.TypeMappings.TypeConverterAttributes).FirstOrDefault();
                    if (typeConverterAttribute != null)
                    {
                        converterType = TryGetTypeConverterFromCustomAttribute(cfg, typeConverterAttribute);
                    }
                }

                if (converterType != null)
                {
                    var converterMethod = converterType.FindMethod("ConvertFrom", cfg.WellKnownTypes.Object, false,
                                                                   cfg.TypeMappings.TypeDescriptorContext, cfg.WellKnownTypes.CultureInfo,
                                                                   cfg.WellKnownTypes.Object);
                    rv = new XamlIlAstNeedsParentStackValueNode(node,
                                                                new XamlIlAstRuntimeCastNode(node,
                                                                                             new XamlIlStaticOrTargetedReturnMethodCallNode(node, converterMethod,
                                                                                                                                            new[]
                    {
                        new XamlIlAstNewClrObjectNode(node,
                                                      new XamlIlAstClrTypeReference(node, converterType, false), null,
                                                      new List <IXamlIlAstValueNode>()),
                        new XamlIlAstContextLocalNode(node, cfg.TypeMappings.TypeDescriptorContext),
                        CreateInvariantCulture(), node
                    }), new XamlIlAstClrTypeReference(node, type, false)));
                    return(true);
                }
            }

            return(false);
        }