public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
            {
                if (node is XamlPropertyAssignmentNode pa)
                {
                    if (pa.Property.Name == "Name" &&
                        pa.Property.DeclaringType.FullName == "Robust.Client.UserInterface.Control")
                    {
                        if (context.ParentNodes().FirstOrDefault() is XamlManipulationGroupNode mg &&
                            mg.Children.OfType <RobustNameScopeRegistrationXamlIlNode>().Any())
                        {
                            return(node);
                        }

                        IXamlAstValueNode value = null;
                        for (var c = 0; c < pa.Values.Count; c++)
                        {
                            if (pa.Values[c].Type.GetClrType().Equals(context.Configuration.WellKnownTypes.String))
                            {
                                value = pa.Values[c];
                                if (!(value is XamlAstTextNode))
                                {
                                    var local = new XamlAstCompilerLocalNode(value);
                                    // Wrap original in local initialization
                                    pa.Values[c] = new XamlAstLocalInitializationNodeEmitter(value, value, local);
                                    // Use local
                                    value = local;
                                }

                                break;
                            }
                        }

                        if (value != null)
                        {
                            var objectType = context.ParentNodes().OfType <XamlAstConstructableObjectNode>().FirstOrDefault()?.Type.GetClrType();
                            return(new XamlManipulationGroupNode(pa)
                            {
                                Children =
                                {
                                    pa,
                                    new RobustNameScopeRegistrationXamlIlNode(value, objectType)
                                }
                            });
                        }
                    }

                    /*else if (pa.Property.CustomAttributes.Select(attr => attr.Type).Intersect(context.Configuration.TypeMappings.DeferredContentPropertyAttributes).Any())
                     * {
                     *  pa.Values[pa.Values.Count - 1] =
                     *      new NestedScopeMetadataNode(pa.Values[pa.Values.Count - 1]);
                     * }*/
                }

                return(node);
            }
Beispiel #2
0
 public override void LoadLocalValue(XamlAstCompilerLocalNode node, IXamlILEmitter codeGen)
 {
     if (_locals.TryGetValue(node, out var local))
     {
         codeGen.Emit(OpCodes.Ldloc, local);
     }
     else
     {
         throw new XamlLoadException("Attempt to read uninitialized local variable", node);
     }
 }
 public IXamlLocal GetLocalForNode(XamlAstCompilerLocalNode node, TBackendEmitter codeGen, bool throwOnUninitialized)
 {
     if (!_locals.TryGetValue(node, out var local))
     {
         if (throwOnUninitialized)
         {
             throw new XamlLoadException("Attempt to read uninitialized local variable", node);
         }
         _locals[node] = local = codeGen.DefineLocal(node.Type);
     }
     return(local);
 }
 public abstract void LoadLocalValue(XamlAstCompilerLocalNode node, TBackendEmitter codeGen);
        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);
        }