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); }