/// <summary> /// Get the backing fields for the <paramref name="propertyDeclaration"/> these are different for readonly dependency properties where the setter returns the DependencyPropertyKey field. /// </summary> internal static bool TryGetBackingFields(PropertyDeclarationSyntax propertyDeclaration, SemanticModel semanticModel, CancellationToken cancellationToken, out BackingFieldOrProperty getField, out BackingFieldOrProperty setField) { getField = default; setField = default; if (propertyDeclaration.TryGetGetter(out var getAccessor) && propertyDeclaration.TryGetSetter(out var setAccessor)) { using (var getterWalker = ClrGetterWalker.Borrow(semanticModel, cancellationToken, getAccessor)) { using (var setterWalker = ClrSetterWalker.Borrow(semanticModel, cancellationToken, setAccessor)) { if (getterWalker.HasError || setterWalker.HasError) { return(false); } if (getterWalker.IsSuccess && BackingFieldOrProperty.TryCreateForDependencyProperty(semanticModel.GetSymbolSafe(getterWalker.Property.Expression, cancellationToken), out getField) && setterWalker.IsSuccess && BackingFieldOrProperty.TryCreateForDependencyProperty(semanticModel.GetSymbolSafe(setterWalker.Property.Expression, cancellationToken), out setField)) { return(true); } var property = semanticModel.GetSymbolSafe(propertyDeclaration, cancellationToken) as IPropertySymbol; return(TryGetBackingFieldsByName(property, semanticModel.Compilation, out getField, out setField)); } } } return(false); }
internal static bool IsAttachedSet(MethodDeclarationSyntax method, SemanticModel semanticModel, CancellationToken cancellationToken, out InvocationExpressionSyntax setValueCall, out BackingFieldOrProperty setField) { setValueCall = null; setField = default(BackingFieldOrProperty); if (method == null || method.ParameterList.Parameters.Count != 2 || !method.ReturnType.IsVoid() || !method.Modifiers.Any(SyntaxKind.StaticKeyword)) { return(false); } using (var walker = ClrSetterWalker.Borrow(semanticModel, cancellationToken, method)) { if (!walker.IsSuccess) { return(false); } setValueCall = walker.SetValue ?? walker.SetCurrentValue; if (setValueCall.Expression is MemberAccessExpressionSyntax memberAccess && memberAccess.IsKind(SyntaxKind.SimpleMemberAccessExpression) && memberAccess.Expression is IdentifierNameSyntax member) { if (method.ParameterList.Parameters[0].Identifier.ValueText != member.Identifier.ValueText) { return(false); } if (setValueCall.TryGetArgumentAtIndex(1, out var arg) && method.ParameterList.Parameters.TryElementAt(1, out var parameter)) { if (arg.Expression is IdentifierNameSyntax argIdentifier && argIdentifier.Identifier.ValueText == parameter.Identifier.ValueText) { return(BackingFieldOrProperty.TryCreateForDependencyProperty(semanticModel.GetSymbolSafe(walker.Property.Expression, cancellationToken), out setField)); } if (arg.Expression is InvocationExpressionSyntax invocation && invocation.TrySingleArgument(out var nestedArg) && nestedArg.Expression is IdentifierNameSyntax nestedArgId && nestedArgId.Identifier.ValueText == parameter.Identifier.ValueText) { return(BackingFieldOrProperty.TryCreateForDependencyProperty(semanticModel.GetSymbolSafe(walker.Property.Expression, cancellationToken), out setField)); } if (arg.Expression is ConditionalExpressionSyntax ternary && ternary.Condition is IdentifierNameSyntax conditionIdentifier && conditionIdentifier.Identifier.ValueText == parameter.Identifier.ValueText) { return(BackingFieldOrProperty.TryCreateForDependencyProperty(semanticModel.GetSymbolSafe(walker.Property.Expression, cancellationToken), out setField)); } } } return(false); } }