コード例 #1
0
            internal void AnalyzeInvocation(SyntaxNodeAnalysisContext context)
            {
                var invocationSyntax = (InvocationExpressionSyntax)context.Node;
                var invokeMethod     = context.SemanticModel.GetSymbolInfo(context.Node).Symbol as IMethodSymbol;

                if (invokeMethod != null)
                {
                    var methodDeclaration = context.Node.FirstAncestorOrSelf <SyntaxNode>(n => MethodSyntaxKinds.Contains(n.Kind()));
                    if (methodDeclaration != null)
                    {
                        if (KnownMethodsToVerifyMainThread.Contains(invokeMethod.Name) || KnownMethodsToSwitchToMainThread.Contains(invokeMethod.Name))
                        {
                            this.methodDeclarationNodes = this.methodDeclarationNodes.SetItem(methodDeclaration, ThreadingContext.MainThread);
                            return;
                        }
                    }

                    // The diagnostic (if any) should underline the method name only.
                    var focusedNode = invocationSyntax.Expression;
                    focusedNode = (focusedNode as MemberAccessExpressionSyntax)?.Name ?? focusedNode;
                    if (!this.AnalyzeTypeWithinContext(invokeMethod.ContainingType, invokeMethod, context, focusedNode))
                    {
                        foreach (var iface in invokeMethod.FindInterfacesImplemented())
                        {
                            if (this.AnalyzeTypeWithinContext(iface, invokeMethod, context, focusedNode))
                            {
                                // Just report the first diagnostic.
                                break;
                            }
                        }
                    }
                }
            }
コード例 #2
0
            private bool AnalyzeTypeWithinContext(ITypeSymbol type, ISymbol symbol, SyntaxNodeAnalysisContext context, SyntaxNode focusDiagnosticOn = null)
            {
                if (type == null)
                {
                    throw new ArgumentNullException(nameof(type));
                }

                bool requiresUIThread = type.TypeKind == TypeKind.Interface &&
                                        type.ContainingAssembly != null &&
                                        IsVisualStudioShellInteropAssembly(type.ContainingAssembly.Name);

                requiresUIThread |= symbol?.Name == "GetService" && type.Name == "Package" && type.BelongsToNamespace(Namespaces.MicrosoftVisualStudioShell);
                requiresUIThread |= symbol != null && !symbol.IsStatic && type.Name == "ServiceProvider" && type.BelongsToNamespace(Namespaces.MicrosoftVisualStudioShell);

                if (requiresUIThread)
                {
                    var threadingContext  = ThreadingContext.Unknown;
                    var methodDeclaration = context.Node.FirstAncestorOrSelf <SyntaxNode>(n => MethodSyntaxKinds.Contains(n.Kind()));
                    if (methodDeclaration != null)
                    {
                        threadingContext = this.methodDeclarationNodes.GetValueOrDefault(methodDeclaration);
                    }

                    if (threadingContext != ThreadingContext.MainThread)
                    {
                        Location location = (focusDiagnosticOn ?? context.Node).GetLocation();
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, location, type.Name));
                        return(true);
                    }
                }

                return(false);
            }
コード例 #3
0
            private void AnalyzeTypeWithinContext(ITypeSymbol type, SyntaxNodeAnalysisContext context, SyntaxNode focusDiagnosticOn = null)
            {
                if (type.TypeKind == TypeKind.Interface &&
                    type.ContainingAssembly != null &&
                    IsVisualStudioShellInteropAssembly(type.ContainingAssembly.Name))
                {
                    var threadingContext  = ThreadingContext.Unknown;
                    var methodDeclaration = context.Node.FirstAncestorOrSelf <SyntaxNode>(n => MethodSyntaxKinds.Contains(n.Kind()));
                    if (methodDeclaration != null)
                    {
                        threadingContext = this.methodDeclarationNodes.GetValueOrDefault(methodDeclaration);
                    }

                    if (threadingContext != ThreadingContext.MainThread)
                    {
                        Location location = (focusDiagnosticOn ?? context.Node).GetLocation();
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, location, type.Name));
                    }
                }
            }