private static bool GetRelativeSourceObjectFromAssignment(
            AstTransformationContext context,
            XamlAstXamlPropertyValueNode relativeSourceProperty,
            out XamlAstObjectNode relativeSourceObject)
        {
            relativeSourceObject = null;
            if (relativeSourceProperty is null)
            {
                return(false);
            }

            if (relativeSourceProperty.Values[0] is XamlMarkupExtensionNode me)
            {
                if (me.Type.GetClrType() != context.GetAvaloniaTypes().RelativeSource)
                {
                    throw new XamlParseException($"Expected an object of type 'Avalonia.Data.RelativeSource'. Found a object of type '{me.Type.GetClrType().GetFqn()}'", me);
                }

                relativeSourceObject = (XamlAstObjectNode)me.Value;
                return(true);
            }

            if (relativeSourceProperty.Values[0] is XamlAstObjectNode on)
            {
                if (on.Type.GetClrType() != context.GetAvaloniaTypes().RelativeSource)
                {
                    throw new XamlParseException($"Expected an object of type 'Avalonia.Data.RelativeSource'. Found a object of type '{on.Type.GetClrType().GetFqn()}'", on);
                }

                relativeSourceObject = on;
                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
        {
            if (node is XamlAstObjectNode ni)
            {
                XamlAstXamlPropertyValueNode propertyNode = null;

                for (var c = ni.Children.Count - 1; c >= 0; c--)
                {
                    var child = ni.Children[c];
                    if (child is IXamlAstValueNode valueNode)
                    {
                        if (propertyNode == null)
                        {
                            var contentProperty = context.Configuration.FindContentProperty(ni.Type.GetClrType());
                            if (contentProperty != null)
                            {
                                propertyNode = new XamlAstXamlPropertyValueNode(ni,
                                                                                new XamlAstClrProperty(ni, contentProperty, context.Configuration),
                                                                                Array.Empty <IXamlAstValueNode>());
                            }
                            else
                            {
                                var adders = XamlTransformHelpers.FindPossibleAdders(context, ni.Type.GetClrType());
                                if (adders.Count == 0)
                                {
                                    // If there's no content property, strip all whitespace-only nodes and continue
                                    WhitespaceNormalization.RemoveWhitespaceNodes(ni.Children);
                                    if (!ni.Children.Contains(child))
                                    {
                                        continue;
                                    }

                                    throw new XamlParseException(
                                              $"No Content property or any Add methods found for type {ni.Type.GetClrType().GetFqn()}",
                                              child);
                                }

                                propertyNode = new XamlAstXamlPropertyValueNode(ni, new XamlAstClrProperty(ni,
                                                                                                           "Content", ni.Type.GetClrType(), null,
                                                                                                           adders.Select(a => new XamlDirectCallPropertySetter(a)
                                {
                                    BinderParameters = { AllowMultiple = true }
                                })),
                                                                                Array.Empty <IXamlAstValueNode>());
                            }
                        }
                        // We are going in reverse order, so insert at the beginning
                        propertyNode.Values.Insert(0, valueNode);
                        ni.Children.RemoveAt(c);
                    }
                }

                if (propertyNode != null)
                {
                    ni.Children.Add(propertyNode);
                }
            }

            return(node);
        }