Пример #1
0
 public XamlPropertyValueManipulationNode(IXamlLineInfo lineInfo,
                                          XamlAstClrProperty property, IXamlAstManipulationNode manipulation)
     : base(lineInfo)
 {
     Property     = property;
     Manipulation = manipulation;
 }
Пример #2
0
 public XamlIlAvaloniaPropertyNode(IXamlLineInfo lineInfo, IXamlType type, XamlAstClrProperty property) : base(lineInfo)
 {
     Type                 = new XamlAstClrTypeReference(this, type, false);
     Property             = property;
     AvaloniaPropertyType = Property.Getter?.ReturnType
                            ?? Property.Setters.First().Parameters[0];
 }
Пример #3
0
 public DependencyProperty(XamlAstClrProperty original, IXamlProperty dependencyPropertyProp,
                           WellKnownWinUITypes types)
     : base(original, original.Name, original.DeclaringType, original.Getter, original.Setters)
 {
     dependencyProperty = dependencyPropertyProp;
     Setters.Insert(0, new BindingSetter(types, original.DeclaringType, dependencyPropertyProp));
 }
Пример #4
0
        public XamlIlAvaloniaProperty(XamlAstClrProperty original, IXamlField field,
                                      AvaloniaXamlIlWellKnownTypes types)
            : base(original, original.Name, original.DeclaringType, original.Getter, original.Setters)
        {
            var assignBinding = original.CustomAttributes.Any(ca => ca.Type.Equals(types.AssignBindingAttribute));

            AvaloniaProperty = field;
            CustomAttributes = original.CustomAttributes;
            if (!assignBinding)
            {
                Setters.Insert(0, new BindingSetter(types, original.DeclaringType, field));
            }

            // Styled and attached properties can be set with a BindingPriority when they're
            // assigned in a ControlTemplate.
            if (field.FieldType.GenericTypeDefinition == types.StyledPropertyT ||
                field.FieldType.GenericTypeDefinition == types.AvaloniaAttachedPropertyT)
            {
                var propertyType = field.FieldType.GenericArguments[0];
                Setters.Insert(0, new SetValueWithPrioritySetter(types, original.DeclaringType, field, propertyType));
                if (!assignBinding)
                {
                    Setters.Insert(1, new BindingWithPrioritySetter(types, original.DeclaringType, field));
                }
            }

            Setters.Insert(0, new UnsetValueSetter(types, original.DeclaringType, field));
        }
Пример #5
0
 public XamlPropertyAssignmentNode(IXamlLineInfo lineInfo,
                                   XamlAstClrProperty property,
                                   IEnumerable <IXamlPropertySetter> setters, IEnumerable <IXamlAstValueNode> values)
     : base(lineInfo)
 {
     Property        = property;
     PossibleSetters = setters.ToList();
     Values          = values.ToList();
 }
Пример #6
0
        public XamlIlAvaloniaProperty(XamlAstClrProperty original, IXamlField field,
                                      AvaloniaXamlIlWellKnownTypes types)
            : base(original, original.Name, original.DeclaringType, original.Getter, original.Setters)
        {
            AvaloniaProperty = field;
            CustomAttributes = original.CustomAttributes;
            if (!original.CustomAttributes.Any(ca => ca.Type.Equals(types.AssignBindingAttribute)))
            {
                Setters.Insert(0, new BindingSetter(types, original.DeclaringType, field));
            }

            Setters.Insert(0, new UnsetValueSetter(types, original.DeclaringType, field));
        }
Пример #7
0
        public static bool EmitProvideValueTarget(XamlIlEmitContext context, IXamlILEmitter emitter,
                                                  XamlAstClrProperty property)
        {
            if (Emit(context, emitter, property))
            {
                return(true);
            }
            var foundClr = property.DeclaringType.Properties.FirstOrDefault(p => p.Name == property.Name);

            if (foundClr == null)
            {
                return(false);
            }
            context
            .Configuration.GetExtra <XamlIlClrPropertyInfoEmitter>()
            .Emit(context, emitter, foundClr);
            return(true);
        }
Пример #8
0
        public static bool Emit(XamlIlEmitContext context, IXamlILEmitter emitter, XamlAstClrProperty property)
        {
            if (property is IXamlIlAvaloniaProperty ap)
            {
                emitter.Ldsfld(ap.AvaloniaProperty);
                return(true);
            }
            var type  = property.DeclaringType;
            var name  = property.Name + "Property";
            var found = type.Fields.FirstOrDefault(f => f.IsStatic && f.Name == name);

            if (found == null)
            {
                return(false);
            }

            emitter.Ldsfld(found);
            return(true);
        }
Пример #9
0
        private bool WantsWhitespaceOnlyElements(TransformerConfiguration config,
                                                 XamlAstClrProperty property)
        {
            var wellKnownTypes = config.WellKnownTypes;

            var acceptsMultipleElements = false;

            foreach (var setter in property.Setters)
            {
                // Skip any dictionary-like setters
                if (setter.Parameters.Count != 1)
                {
                    continue;
                }

                var parameterType = setter.Parameters[0];
                if (!setter.BinderParameters.AllowMultiple)
                {
                    // If the property can accept a scalar string, it'll get whitespace nodes by default
                    if (parameterType.Equals(wellKnownTypes.String) || parameterType.Equals(wellKnownTypes.Object))
                    {
                        return(true);
                    }
                }
                else
                {
                    acceptsMultipleElements = true;
                }
            }

            // A collection-like property will only receive whitespace-only nodes if the
            // property type can be deduced, and that type is annotated as whitespace significant
            if (acceptsMultipleElements &&
                property.Getter != null &&
                config.IsWhitespaceSignificantCollection(property.Getter.ReturnType))
            {
                return(true);
            }

            return(false);
        }
Пример #10
0
        public static bool TryConvertValue(AstTransformationContext context,
                                           IXamlAstValueNode node, IXamlType type, XamlAstClrProperty propertyContext,
                                           out IXamlAstValueNode 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 XamlAstTextNode 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 = TypeReferenceResolver.ResolveType(context, tn.Text, false, tn, true);
                    rv = new XamlTypeExtensionNode(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 XamlLoadMethodDelegateNode(tn, context.RootObject, type, handler);
                        return(true);
                    }
                }
            }

            IXamlAstValueNode CreateInvariantCulture() =>
            new XamlStaticOrTargetedReturnMethodCallNode(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 <IXamlAstValueNode> {
                    node
                };
                if (parser.Parameters.Count == 2)
                {
                    args.Add(CreateInvariantCulture());
                }

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

            if (cfg.TypeMappings.TypeDescriptorContext != null)
            {
                IXamlType 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 XamlAstNeedsParentStackValueNode(node,
                                                              new XamlAstRuntimeCastNode(node,
                                                                                         new XamlStaticOrTargetedReturnMethodCallNode(node, converterMethod,
                                                                                                                                      new[]
                    {
                        new XamlAstNewClrObjectNode(node,
                                                    new XamlAstClrTypeReference(node, converterType, false), null,
                                                    new List <IXamlAstValueNode>()),
                        new XamlAstContextLocalNode(node, cfg.TypeMappings.TypeDescriptorContext),
                        CreateInvariantCulture(), node
                    }), new XamlAstClrTypeReference(node, type, false)));
                    return(true);
                }
            }

            return(false);
        }