Exemple #1
0
 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);
        }
Exemple #3
0
 public XamlIlPropertyValueManipulationNode(IXamlIlLineInfo lineInfo,
                                            IXamlIlProperty property, IXamlIlAstManipulationNode manipulation)
     : base(lineInfo)
 {
     Property     = property;
     Manipulation = manipulation;
 }
Exemple #4
0
        public XamlIlAstClrProperty(IXamlIlLineInfo lineInfo, IXamlIlProperty property,
                                    XamlIlTransformerConfiguration cfg) : base(lineInfo)
        {
            Name   = property.Name;
            Getter = property.Getter;
            if (property.Setter != null)
            {
                Setters.Add(new XamlIlDirectCallPropertySetter(property.Setter));
            }
            CustomAttributes = property.CustomAttributes.ToList();
            DeclaringType    = (property.Getter ?? property.Setter)?.DeclaringType;
            var typeConverterAttributes = cfg.GetCustomAttribute(property, cfg.TypeMappings.TypeConverterAttributes);

            if (typeConverterAttributes != null)
            {
                foreach (var attr in typeConverterAttributes)
                {
                    var typeConverter =
                        XamlIlTransformHelpers.TryGetTypeConverterFromCustomAttribute(cfg, attr);
                    if (typeConverter != null)
                    {
                        TypeConverters[property.PropertyType] = typeConverter;
                        break;
                    }
                }
            }
        }
 public XamlIlPropertyEqualsSelector(XamlIlSelectorNode previous,
                                     IXamlIlProperty property,
                                     IXamlIlAstValueNode value)
     : base(previous)
 {
     Property = property;
     Value    = value;
 }
Exemple #6
0
 public XamlIlMarkupExtensionNode(IXamlIlLineInfo lineInfo, IXamlIlProperty property, IXamlIlMethod provideValue,
                                  IXamlIlAstValueNode value, IXamlIlWrappedMethod manipulation) : base(lineInfo)
 {
     Property     = property;
     ProvideValue = provideValue;
     Value        = value;
     Manipulation = manipulation;
 }
        public static List <IXamlIlAstManipulationNode> GeneratePropertyAssignments(XamlIlAstTransformationContext context,
                                                                                    IXamlIlProperty property, List <IXamlIlAstValueNode> nodes)
        {
            var tmp = nodes.Cast <IXamlIlAstNode>().ToList();

            GeneratePropertyAssignments(context, property, tmp.Count,
                                        i => (IXamlIlAstValueNode)tmp[i],
                                        (i, v) => tmp[i] = v);
            return(tmp.Cast <IXamlIlAstManipulationNode>().ToList());
        }
 public bool Equals(IXamlIlProperty other)
 {
     if (other == null)
     {
         return(false);
     }
     return(other.Name == Name &&
            other.Getter.Equals(Getter) &&
            other.Setter.Equals(Setter));
 }
Exemple #9
0
 public XamlIlAstClrProperty(IXamlIlLineInfo lineInfo, IXamlIlProperty property) : base(lineInfo)
 {
     Name   = property.Name;
     Getter = property.Getter;
     if (property.Setter != null)
     {
         Setters.Add(new XamlIlDirectCallPropertySetter(property.Setter));
     }
     CustomAttributes = property.CustomAttributes.ToList();
     DeclaringType    = (property.Getter ?? property.Setter)?.DeclaringType;
 }
Exemple #10
0
            public bool Equals(IXamlIlProperty other)
            {
                var otherProp = ((SreProperty)other)?.Member;

                if (otherProp == null)
                {
                    return(false);
                }
                return(otherProp?.DeclaringType?.Equals(Member.DeclaringType) == true &&
                       Member.Name == otherProp.Name);
            }
        public static void GeneratePropertyAssignments(XamlIlAstTransformationContext context,
                                                       IXamlIlProperty contentProperty,
                                                       int count, Func <int, IXamlIlAstValueNode> getNode, Action <int, IXamlIlAstNode> setNode)
        {
            var type = contentProperty.PropertyType;

            // Markup extension ?
            if (contentProperty.Setter?.IsPublic == true &&
                count == 1 &&
                TryConvertMarkupExtension(context, getNode(0),
                                          contentProperty, out var me))
            {
                setNode(0, me);
            }
            // Direct property assignment?
            else if (contentProperty.Setter?.IsPublic == true &&
                     count == 1 &&
                     context.Configuration.TryGetCorrectlyTypedValue(getNode(0),
                                                                     contentProperty.PropertyType,
                                                                     out var value))
            {
                setNode(0,
                        new XamlIlPropertyAssignmentNode(getNode(0), contentProperty, value));
            }
            // Collection property?
            else if (contentProperty.Getter?.IsPublic == true)
            {
                for (var ind = 0; ind < count; ind++)
                {
                    if (TryCallAdd(context, contentProperty, contentProperty.PropertyType, getNode(ind), out var addCall))
                    {
                        setNode(ind, addCall);
                    }
                    else
                    {
                        var propFqn  = contentProperty.PropertyType.GetFqn();
                        var valueFqn = getNode(ind).Type.GetClrType().GetFqn();
                        throw new XamlIlLoadException(
                                  $"Unable to directly convert {valueFqn} to {propFqn} find a suitable Add({valueFqn}) on type {propFqn}",
                                  getNode(ind));
                    }
                }
            }
            else
            {
                throw new XamlIlLoadException(
                          $"Unable to handle {getNode(0).Type.GetClrType().GetFqn()} assignment to {contentProperty.Name} " +
                          $"as either direct assignment or collection initialization, check if value type matches property type or that property type has proper Add method",
                          getNode(0));
            }
        }
Exemple #12
0
        public static bool Emit(XamlIlEmitContext context, IXamlIlEmitter emitter, IXamlIlProperty property)
        {
            var type  = (property.Getter ?? property.Setter).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);
        }
        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);
        }
Exemple #14
0
 public bool Equals(IXamlIlProperty other) => ((SreProperty)other)?.Member.Equals(Member) == true;
Exemple #15
0
 public bool Equals(IXamlIlProperty other) => other is CecilProperty cp && cp.Property == Property;
Exemple #16
0
 public IXamlIlCustomAttribute GetCustomAttribute(IXamlIlProperty property, IXamlIlType attributeType)
 {
     return(null);
 }
        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);
        }
Exemple #18
0
 public XamlIlAstClrPropertyReference(IXamlIlLineInfo lineInfo, IXamlIlProperty property) : base(lineInfo)
 {
     Property = property;
 }