| File: BindingTransformer.cs | Web Access |
| Project: src\src\Controls\src\BindingSourceGen\Controls.BindingSourceGen.csproj (Microsoft.Maui.Controls.BindingSourceGen) |
namespace Microsoft.Maui.Controls.BindingSourceGen; public interface IBindingInvocationTransformer { BindingInvocationDescription Transform(BindingInvocationDescription BindingInvocationDescription); } public class ReferenceTypesConditionalAccessTransformer : IBindingInvocationTransformer { public BindingInvocationDescription Transform(BindingInvocationDescription BindingInvocationDescription) { var path = TransformPath(BindingInvocationDescription); return BindingInvocationDescription with { Path = path }; } private static EquatableArray<IPathPart> TransformPath(BindingInvocationDescription BindingInvocationDescription) { var newPath = new List<IPathPart>(); foreach (var pathPart in BindingInvocationDescription.Path) { var sourceIsReferenceType = newPath.Count == 0 && !BindingInvocationDescription.SourceType.IsValueType; var previousPartIsReferenceType = newPath.Count > 0 && PreviousPartIsReferenceType(newPath.Last()); if (pathPart is not MemberAccess && pathPart is not IndexAccess) { newPath.Add(pathPart); } else if (sourceIsReferenceType || previousPartIsReferenceType) { newPath.Add(new ConditionalAccess(pathPart)); } else { newPath.Add(pathPart); } } return new EquatableArray<IPathPart>(newPath.ToArray()); static bool PreviousPartIsReferenceType(IPathPart previousPathPart) => previousPathPart switch { MemberAccess memberAccess => !memberAccess.IsValueType, IndexAccess indexAccess => !indexAccess.IsValueType, ConditionalAccess { Part: var inner } => PreviousPartIsReferenceType(inner), _ => false, }; } }