private static void HandlePotentialGetMethod(SyntaxNodeAnalysisContext context, BlockSyntax body)
        {
            if (body == null)
            {
                return;
            }

            using (var pooled = ClrGetterWalker.Create(context.SemanticModel, context.CancellationToken, context.Node))
            {
                if (pooled.Item.HasError)
                {
                    return;
                }

                if (pooled.Item.IsSuccess)
                {
                    var returnStatementSyntax = pooled.Item.GetValue.FirstAncestorOrSelf <ReturnStatementSyntax>();
                    foreach (var statement in body.Statements)
                    {
                        if (statement != returnStatementSyntax)
                        {
                            context.ReportDiagnostic(Diagnostic.Create(Descriptor, statement.GetLocation()));
                            return;
                        }
                    }
                }
            }
        }
예제 #2
0
        private static bool IsAttachedGetMethod(MethodDeclarationSyntax method, SemanticModel semanticModel, CancellationToken cancellationToken, out IFieldSymbol getField)
        {
            getField = null;
            if (method == null ||
                method.ParameterList.Parameters.Count != 1 ||
                method.ReturnType.IsVoid() ||
                !method.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                return(false);
            }

            using (var walker = ClrGetterWalker.Create(semanticModel, cancellationToken, method))
            {
                var memberAccess = walker.GetValue?.Expression as MemberAccessExpressionSyntax;
                var member       = memberAccess?.Expression as IdentifierNameSyntax;
                if (memberAccess == null ||
                    member == null ||
                    !memberAccess.IsKind(SyntaxKind.SimpleMemberAccessExpression))
                {
                    return(false);
                }

                if (method.ParameterList.Parameters[0].Identifier.ValueText != member.Identifier.ValueText)
                {
                    return(false);
                }

                return(walker.Property.TryGetSymbol(semanticModel, cancellationToken, out getField));
            }
        }
예제 #3
0
        /// <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 IFieldSymbol getField, out IFieldSymbol setField)
        {
            getField = null;
            setField = null;
            if (propertyDeclaration.TryGetAccessorDeclaration(SyntaxKind.GetAccessorDeclaration, out AccessorDeclarationSyntax getAccessor) &&
                propertyDeclaration.TryGetAccessorDeclaration(SyntaxKind.SetAccessorDeclaration, out AccessorDeclarationSyntax setAccessor))
            {
                using (var pooled = ClrGetterWalker.Create(semanticModel, cancellationToken, getAccessor))
                {
                    using (var setterWalker = ClrSetterWalker.Create(semanticModel, cancellationToken, setAccessor))
                    {
                        if (pooled.Item.HasError ||
                            setterWalker.Item.HasError)
                        {
                            return(false);
                        }

                        if (pooled.Item.IsSuccess &&
                            pooled.Item.Property.TryGetSymbol(semanticModel, cancellationToken, out getField) &&
                            setterWalker.Item.IsSuccess &&
                            setterWalker.Item.Property.TryGetSymbol(semanticModel, cancellationToken, out setField))
                        {
                            return(true);
                        }

                        var property = semanticModel.GetSymbolSafe(propertyDeclaration, cancellationToken) as IPropertySymbol;
                        return(TryGetBackingFieldsByName(property, out getField, out setField));
                    }
                }
            }

            return(false);
        }
예제 #4
0
        public static ClrGetterWalker Create(SemanticModel semanticModel, CancellationToken cancellationToken, SyntaxNode getter)
        {
            ClrGetterWalker walker;

            if (!Cache.TryDequeue(out walker))
            {
                walker = new ClrGetterWalker();
            }

            walker.HasError          = false;
            walker.GetValue          = null;
            walker.semanticModel     = semanticModel;
            walker.cancellationToken = cancellationToken;
            walker.Visit(getter);
            return(walker);
        }