Exemple #1
0
 static void ExtractXamlDirectAssignments(XamlManipulationGroupNode manipGrp, XamlManipulationGroupNode xamlDirectAssignmentsNode, XamlManipulationGroupNode standardAssignmentsNode)
 {
     foreach (var manip in manipGrp.Children)
     {
         if (manip is XamlManipulationGroupNode nestedGrp)
         {
             ExtractXamlDirectAssignments(nestedGrp, xamlDirectAssignmentsNode, standardAssignmentsNode);
         }
         else if (manip is XamlPropertyAssignmentNode assign)
         {
             var xamlDirectSetters = assign.PossibleSetters.OfType <IXamlDirectSetter>().ToList();
             if (xamlDirectSetters.Count != 0)
             {
                 assign.PossibleSetters.Clear();
                 assign.PossibleSetters.AddRange(xamlDirectSetters);
                 xamlDirectAssignmentsNode.Children.Add(assign);
             }
             else
             {
                 standardAssignmentsNode.Children.Add(assign);
             }
         }
         else
         {
             standardAssignmentsNode.Children.Add(manip);
         }
     }
 }
Exemple #2
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)
        {
            var usableAttrs = context.Configuration.TypeMappings.UsableDuringInitializationAttributes;

            if (!(usableAttrs?.Count > 0))
            {
                return(node);
            }
            bool UsableDuringInitialization(IXamlType type)
            {
                foreach (var attr in type.CustomAttributes)
                {
                    foreach (var attrType in usableAttrs)
                    {
                        if (attr.Type.Equals(attrType))
                        {
                            return(attr.Parameters.Count == 0 || attr.Parameters[0] as bool? == true);
                        }
                    }
                }

                if (type.BaseType != null)
                {
                    return(UsableDuringInitialization(type.BaseType));
                }
                return(false);
            }

            bool TryConvert(
                IXamlAstValueNode checkedNode, out IXamlAstValueNode value, out IXamlAstManipulationNode deferred)
            {
                value    = null;
                deferred = null;
                if (!(checkedNode is XamlValueWithManipulationNode manipulation &&
                      manipulation.Manipulation is XamlObjectInitializationNode initializer &&
                      UsableDuringInitialization(manipulation.Value.Type.GetClrType())))
                {
                    return(false);
                }
                initializer.SkipBeginInit = true;
                var local = new XamlAstCompilerLocalNode(manipulation.Value, manipulation.Value.Type.GetClrTypeReference());

                value    = new XamlValueNodeWithBeginInit(new XamlAstLocalInitializationNodeEmitter(local, manipulation.Value, local));
                deferred = new XamlAstManipulationImperativeNode(initializer,
                                                                 new XamlAstImperativeValueManipulation(initializer, local, initializer));
                return(true);
            }

            if (node is XamlPropertyAssignmentNode assignment)
            {
                if (!TryConvert(assignment.Values.Last(), out var nvalue, out var deferred))
                {
                    return(node);
                }

                assignment.Values[assignment.Values.Count - 1] = nvalue;
                return(new XamlManipulationGroupNode(assignment)
                {
                    Children =
                    {
                        assignment,
                        deferred
                    }
                });
            }
            else if (node is XamlNoReturnMethodCallNode call)
            {
                var deferredNodes = new List <IXamlAstManipulationNode>();
                for (var c = 0; c < call.Arguments.Count; c++)
                {
                    var arg = call.Arguments[c];
                    if (TryConvert(arg, out var narg, out var deferred))
                    {
                        call.Arguments[c] = narg;
                        deferredNodes.Add(deferred);
                    }
                }

                if (deferredNodes.Count != 0)
                {
                    var grp = new XamlManipulationGroupNode(call);
                    grp.Children.Add(call);
                    grp.Children.AddRange(deferredNodes);
                    return(grp);
                }
            }

            return(node);
        }