Exemple #1
0
        public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
        {
            if (node is XamlValueWithManipulationNode valWithManip &&
                TryGetNewObjectNodeForXamlDirect(valWithManip, out var newObj) &&
                newObj.Arguments.Count == 0)
            {
                if (!(valWithManip.Manipulation is XamlObjectInitializationNode init) ||
                    !(init.Manipulation is XamlManipulationGroupNode manipGrp))
                {
                    throw new XamlParseException(
                              "Unable to find the object initialization node inside object creation.", node);
                }

                IXamlType objType = newObj.Type.GetClrType();
                if (objType.Assembly != context.GetWinUITypes().WinUIControlsAssembly)
                {
                    // Only built-in controls have XamlDirect support.
                    // Remove the XamlDirect setters since XamlDirect isn't worth using once the object
                    // is created and return.
                    RemoveXamlDirectSettersFromAssignments(manipGrp);
                    return(node);
                }
                IXamlField typeIndex = context.GetWinUITypes().XamlTypeIndex.GetAllFields().FirstOrDefault(fld => fld.Name == objType.Name);
                if (typeIndex is null)
                {
                    // We didn't find a matching type index, so we can't use XamlDirect.
                    // Remove the XamlDirect setters since XamlDirect isn't worth using once the object
                    // is created and return.
                    RemoveXamlDirectSettersFromAssignments(manipGrp);

                    return(node);
                }
                IXamlAstValueNode constructedObjNode = new XamlDirectNewObjectNode(newObj, context.GetWinUITypes().IXamlDirectObject, typeIndex);
                var xamlDirectAssignmentsNode        = new XamlManipulationGroupNode(constructedObjNode);
                var standardAssignmentsNode          = new XamlManipulationGroupNode(constructedObjNode);

                ExtractXamlDirectAssignments(manipGrp, xamlDirectAssignmentsNode, standardAssignmentsNode);

                if (xamlDirectAssignmentsNode.Children.Count != 0)
                {
                    constructedObjNode = new XamlValueWithManipulationNode(constructedObjNode, constructedObjNode, xamlDirectAssignmentsNode);
                }

                if (standardAssignmentsNode.Children.Count == 0)
                {
                    node = new XamlObjectFromDirectObjectNode(constructedObjNode, newObj.Type);
                }
                else
                {
                    valWithManip.Value = new XamlObjectFromDirectObjectNode(constructedObjNode, newObj.Type);
                    init.Manipulation  = standardAssignmentsNode;
                }
            }
            return(node);
        public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
        {
            // By the time this transform runs, either all setters will be XamlDirect setters
            // or none will be.
            if (node is XamlPropertyAssignmentNode assign &&
                assign.PossibleSetters[0] is IXamlDirectSetter)
            {
                foreach (var setter in assign.PossibleSetters)
                {
                    IXamlDirectSetter directSetter = (IXamlDirectSetter)setter;

                    // Up to this point, the type of the setter parameter matches the actual property type
                    // so that the compiler correctly resolves the setter as a possible setter.
                    // For the emit phase, we need to change the setter type to match the actual type
                    // that the emitted code expects.
                    // Here we change the setter type from a DependencyObject-derived type to IXamlDirectObject
                    // so that the emitters know that the actual expected parameter type is IXamlDirectObject.
                    // Additionally, if we are setting a property that is type object with a DependencyObject-derived object,
                    // we need to use the IXamlDirectObject setter.
                    if (!(directSetter is XamlDirectEventSetter))
                    {
                        if (context.GetWinUITypes().DependencyObject.IsAssignableFrom(directSetter.Parameters[0]))
                        {
                            directSetter.ChangeEmitSetterType(context.GetWinUITypes().IXamlDirectObject);
                        }
                        else if (directSetter.Parameters[0] == context.Configuration.WellKnownTypes.Object)
                        {
                            if (context.GetWinUITypes().DependencyObject.IsAssignableFrom(assign.Values[0].Type.GetClrType()))
                            {
                                directSetter.ChangeEmitSetterType(context.GetWinUITypes().IXamlDirectObject);
                            }
                        }
                    }
                }

                for (int i = 0; i < assign.Values.Count; i++)
                {
                    if (assign.Values[i] is XamlObjectFromDirectObjectNode objFromDirect)
                    {
                        assign.Values[i] = objFromDirect.Value;
                    }
                    else if (assign.Values[i] is XamlValueWithManipulationNode || assign.PossibleSetters[0].Parameters[0] == context.GetWinUITypes().IXamlDirectObject)
                    {
                        assign.Values[i] = new XamlDirectObjectFromObjectNode(assign.Values[0], context.GetWinUITypes().IXamlDirectObject);
                    }
                }
            }
            return(node);
        }
 public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
 {
     if (node is XamlAstClrProperty prop)
     {
         if (prop.DeclaringType.Assembly == context.GetWinUITypes().WinUIControlsAssembly)
         {
             IXamlField propertyIndexMaybe = context.GetWinUITypes().XamlPropertyIndex.Fields.FirstOrDefault(f => f.Name == $"{prop.DeclaringType.Name}_{prop.Name}");
             if (propertyIndexMaybe != null)
             {
                 prop.Setters.Insert(0, new XamlDirectSetter(context.GetWinUITypes(), prop.Getter.ReturnType, prop.DeclaringType, propertyIndexMaybe));
                 foreach (var adder in XamlTransformHelpers.FindPossibleAdders(context, prop.Getter.ReturnType))
                 {
                     if (adder.Parameters.Count == 1)
                     {
                         prop.Setters.Add(new XamlDirectAdderSetter(context.GetWinUITypes(), adder.Parameters[0], prop.DeclaringType, propertyIndexMaybe));
                     }
                 }
                 return(prop);
             }
             IXamlField eventIndexMaybe = context.GetWinUITypes().XamlEventIndex.Fields.FirstOrDefault(f => f.Name == $"{prop.DeclaringType.Name}_{prop.Name}");
             if (eventIndexMaybe != null)
             {
                 prop.Setters.Insert(0, new XamlDirectEventSetter(context.GetWinUITypes(), prop.Setters[0].Parameters[0], prop.DeclaringType, eventIndexMaybe));
                 return(prop);
             }
         }
     }
     return(node);
 }
 public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
 {
     if (node is XamlAstClrProperty prop)
     {
         IXamlProperty dependencyPropertyProp = prop.DeclaringType.Properties
                                                .FirstOrDefault(p => p.Getter?.IsStatic == true &&
                                                                p.Name == prop.Name + "Property" &&
                                                                p.PropertyType == context.GetWinUITypes().DependencyProperty);
         if (dependencyPropertyProp is null)
         {
             return(node);
         }
         return(new DependencyProperty(prop, dependencyPropertyProp, context.GetWinUITypes()));
     }
     return(node);
 }