示例#1
0
        public void TestDiagnosticArguments()
        {
            var arguments = new DiagnosticArguments(
                forcedAnalysis: false,
                reportSuppressedDiagnostics: true,
                logAnalyzerExecutionTime: false,
                projectId: ProjectId.CreateNewId("project"),
                optionSetChecksum: Checksum.Null,
                analyzerIds: new[] { "analyzer1", "analyzer2" });

            VerifyJsonSerialization(arguments, (x, y) =>
            {
                if (x.ForcedAnalysis == y.ForcedAnalysis &&
                    x.ReportSuppressedDiagnostics == y.ReportSuppressedDiagnostics &&
                    x.LogAnalyzerExecutionTime == y.LogAnalyzerExecutionTime &&
                    x.ProjectId == y.ProjectId &&
                    x.OptionSetChecksum == y.OptionSetChecksum &&
                    x.AnalyzerIds.Length == y.AnalyzerIds.Length &&
                    x.AnalyzerIds.Except(y.AnalyzerIds).Count() == 0)
                {
                    return(0);
                }

                return(1);
            });
        }
            private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync(
                RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, bool forcedAnalysis, CancellationToken cancellationToken)
            {
                var solution = project.Solution;

                using var pooledObject = SharedPools.Default <Dictionary <string, DiagnosticAnalyzer> >().GetPooledObject();
                var analyzerMap = pooledObject.Object;

                analyzerMap.AppendAnalyzerMap(analyzerDriver.Analyzers.Where(a => forcedAnalysis || !a.IsOpenFileOnly(solution.Options)));
                if (analyzerMap.Count == 0)
                {
                    return(DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty);
                }

                var argument = new DiagnosticArguments(
                    forcedAnalysis, analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime,
                    project.Id, analyzerMap.Keys.ToArray());

                var result = await client.TryRunRemoteAsync(
                    WellKnownServiceHubServices.CodeAnalysisService,
                    nameof(IRemoteDiagnosticAnalyzerService.CalculateDiagnosticsAsync),
                    solution,
                    new object[] { argument },
                    callbackTarget : null,
                    (s, c) => ReadCompilerAnalysisResultAsync(s, analyzerMap, project, c),
                    cancellationToken).ConfigureAwait(false);

                return(result.HasValue ? result.Value : DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty);
            }
        public void TestDiagnosticArguments()
        {
            var projectId = ProjectId.CreateNewId("project");
            var arguments = new DiagnosticArguments(
                reportSuppressedDiagnostics: true,
                logPerformanceInfo: true,
                getTelemetryInfo: true,
                documentId: DocumentId.CreateNewId(projectId),
                documentSpan: new TextSpan(0, 1),
                documentAnalysisKind: AnalysisKind.Syntax,
                projectId: projectId,
                analyzerIds: new[] { "analyzer1", "analyzer2" });

            VerifyJsonSerialization(arguments, (x, y) =>
            {
                if (x.ReportSuppressedDiagnostics == y.ReportSuppressedDiagnostics &&
                    x.LogPerformanceInfo == y.LogPerformanceInfo &&
                    x.GetTelemetryInfo == y.GetTelemetryInfo &&
                    x.DocumentId == y.DocumentId &&
                    x.DocumentSpan == y.DocumentSpan &&
                    x.DocumentAnalysisKind == y.DocumentAnalysisKind &&
                    x.ProjectId == y.ProjectId &&
                    x.AnalyzerIds.Length == y.AnalyzerIds.Length &&
                    x.AnalyzerIds.Except(y.AnalyzerIds).Count() == 0)
                {
                    return(0);
                }

                return(1);
            });
        }
示例#4
0
        /// <summary>
        /// This is top level entry point for diagnostic calculation from client (VS).
        ///
        /// This will be called by ServiceHub/JsonRpc framework
        /// </summary>
        public Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string streamName, CancellationToken cancellationToken)
        {
            return(RunServiceAsync(async() =>
            {
                // if this analysis is explicitly asked by user, boost priority of this request
                using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectId.DebugName, cancellationToken))
                    using (arguments.ForcedAnalysis ? UserOperationBooster.Boost() : default)
                    {
                        try
                        {
                            // entry point for diagnostic service
                            var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);

                            var optionSet = await RoslynServices.AssetService.GetAssetAsync <OptionSet>(arguments.OptionSetChecksum, cancellationToken).ConfigureAwait(false);
                            var projectId = arguments.ProjectId;
                            var analyzers = RoslynServices.AssetService.GetGlobalAssetsOfType <AnalyzerReference>(cancellationToken);

                            var result = await(new DiagnosticComputer(solution.GetProject(projectId))).GetDiagnosticsAsync(
                                analyzers, optionSet, arguments.AnalyzerIds, arguments.ReportSuppressedDiagnostics, arguments.LogAnalyzerExecutionTime, cancellationToken).ConfigureAwait(false);

                            await SerializeDiagnosticResultAsync(streamName, result, cancellationToken).ConfigureAwait(false);
                        }
                        catch (IOException)
                        {
                            // direct stream to send over result has closed before we
                            // had chance to check cancellation
                        }
                    }
            }, cancellationToken));
        }
        private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync(
            RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, CancellationToken cancellationToken)
        {
            var solution = project.Solution;

            var snapshotService = solution.Workspace.Services.GetService <ISolutionChecksumService>();

            // TODO: this should be moved out
            var hostChecksums = GetHostAnalyzerReferences(snapshotService, _analyzerService.GetHostAnalyzerReferences(), cancellationToken);
            var analyzerMap   = CreateAnalyzerMap(analyzerDriver.Analyzers.Where(a => !a.MustRunInProcess()));

            if (analyzerMap.Count == 0)
            {
                return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty));
            }

            // TODO: send telemetry on session
            using (var session = await client.CreateCodeAnalysisServiceSessionAsync(solution, cancellationToken).ConfigureAwait(false))
            {
                var argument = new DiagnosticArguments(
                    analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics,
                    analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime,
                    project.Id, hostChecksums, analyzerMap.Keys.ToArray());

                var result = await session.InvokeAsync(
                    WellKnownServiceHubServices.CodeAnalysisService_CalculateDiagnosticsAsync,
                    new object[] { argument },
                    (s, c) => GetCompilerAnalysisResultAsync(s, analyzerMap, project, c)).ConfigureAwait(false);

                ReportAnalyzerExceptions(project, result.Exceptions);

                return(result);
            }
        }
示例#6
0
        /// <summary>
        /// This is top level entry point for diagnostic calculation from client (VS).
        ///
        /// This will be called by ServiceHub/JsonRpc framework
        /// </summary>
        public async Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string streamName)
        {
            using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectIdDebugName, CancellationToken))
            {
                try
                {
                    var optionSet = await RoslynServices.AssetService.GetAssetAsync <OptionSet>(arguments.GetOptionSetChecksum(), CancellationToken).ConfigureAwait(false);

                    // entry point for diagnostic service
                    var solution = await GetSolutionWithSpecificOptionsAsync(optionSet).ConfigureAwait(false);

                    var projectId = arguments.GetProjectId();
                    var analyzers = await GetHostAnalyzerReferences(arguments.GetHostAnalyzerChecksums()).ConfigureAwait(false);

                    var result = await(new DiagnosticComputer(solution.GetProject(projectId))).GetDiagnosticsAsync(
                        analyzers, arguments.AnalyzerIds, arguments.ReportSuppressedDiagnostics, arguments.LogAnalyzerExecutionTime, CancellationToken).ConfigureAwait(false);

                    await SerializeDiagnosticResultAsync(streamName, result).ConfigureAwait(false);
                }
                catch (IOException)
                {
                    // stream to send over result has closed before we
                    // had chance to check cancellation
                }
                catch (OperationCanceledException)
                {
                    // rpc connection has closed.
                    // this can happen if client side cancelled the
                    // operation
                }
            }
        }
        /// <summary>
        /// Calculate dignostics. this works differently than other ones such as todo comments or designer attribute scanner
        /// since in proc and out of proc runs quite differently due to concurrency and due to possible amount of data
        /// that needs to pass through between processes
        /// </summary>
        public Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, string pipeName, CancellationToken cancellationToken)
        {
            return(RunServiceAsync(async() =>
            {
                // if this analysis is explicitly asked by user, boost priority of this request
                using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectId.DebugName, cancellationToken))
                    using (arguments.ForcedAnalysis ? UserOperationBooster.Boost() : default)
                    {
                        // entry point for diagnostic service
                        var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);

                        var projectId = arguments.ProjectId;
                        var analyzers = RoslynServices.AssetService.GetGlobalAssetsOfType <AnalyzerReference>(cancellationToken);

                        var result = await new DiagnosticComputer(solution.GetProject(projectId)).GetDiagnosticsAsync(
                            analyzers, arguments.AnalyzerIds, arguments.ReportSuppressedDiagnostics, arguments.LogAnalyzerExecutionTime, cancellationToken).ConfigureAwait(false);

                        await RemoteEndPoint.WriteDataToNamedPipeAsync(pipeName, result, (writer, data, cancellationToken) =>
                        {
                            var(diagnostics, telemetry, exceptions) = DiagnosticResultSerializer.WriteDiagnosticAnalysisResults(writer, data, cancellationToken);

                            // save log for debugging
                            Log(TraceEventType.Information, $"diagnostics: {diagnostics}, telemetry: {telemetry}, exceptions: {exceptions}");

                            return Task.CompletedTask;
                        }, cancellationToken).ConfigureAwait(false);
                    }
            }, cancellationToken));
        }
示例#8
0
        public void TestDiagnosticArguments()
        {
            var arguments = new DiagnosticArguments(
                reportSuppressedDiagnostics: true,
                logAnalyzerExecutionTime: false,
                projectId: ProjectId.CreateNewId("project"),
                optionSetChecksum: Checksum.Null,
                hostAnalyzerChecksums: ImmutableArray.CreateRange(new[] { new Checksum(Guid.NewGuid().ToByteArray()), new Checksum(Guid.NewGuid().ToByteArray()) }),
                analyzerIds: new[] { "analyzer1", "analyzer2" });

            VerifyJsonSerialization(arguments, (x, y) =>
            {
                if (x.ReportSuppressedDiagnostics == y.ReportSuppressedDiagnostics &&
                    x.LogAnalyzerExecutionTime == y.LogAnalyzerExecutionTime &&
                    x.ProjectId == y.ProjectId &&
                    x.OptionSetChecksum == y.OptionSetChecksum &&
                    x.HostAnalyzerChecksums.Length == y.HostAnalyzerChecksums.Length &&
                    x.HostAnalyzerChecksums.Except(y.HostAnalyzerChecksums).Count() == 0 &&
                    x.AnalyzerIds.Length == y.AnalyzerIds.Length &&
                    x.AnalyzerIds.Except(y.AnalyzerIds).Count() == 0)
                {
                    return(0);
                }

                return(1);
            });
        }
        /// <summary>
        /// This is top level entry point for diagnostic calculation from client (VS).
        ///
        /// This will be called by ServiceHub/JsonRpc framework
        /// </summary>
        public async Task CalculateDiagnosticsAsync(DiagnosticArguments arguments, byte[] solutionChecksum, string streamName)
        {
            try
            {
                // entry point for diagnostic service
                var solution = await RoslynServices.SolutionService.GetSolutionAsync(new Checksum(solutionChecksum), CancellationToken).ConfigureAwait(false);

                var projectId = arguments.GetProjectId();
                var analyzers = await GetHostAnalyzerReferences(arguments.GetHostAnalyzerChecksums()).ConfigureAwait(false);

                var result = await(new DiagnosticComputer(solution.GetProject(projectId))).GetDiagnosticsAsync(
                    analyzers, arguments.AnalyzerIds, arguments.ReportSuppressedDiagnostics, arguments.LogAnalyzerExecutionTime, CancellationToken).ConfigureAwait(false);

                await SerializeDiagnosticResultAsync(streamName, result).ConfigureAwait(false);
            }
            catch (IOException)
            {
                // stream to send over result has closed before we
                // had chance to check cancellation
            }
            catch (OperationCanceledException)
            {
                // rpc connection has closed.
                // this can happen if client side cancelled the
                // operation
            }
        }
示例#10
0
        /// <summary>
        /// Calculate dignostics. this works differently than other ones such as todo comments or designer attribute scanner
        /// since in proc and out of proc runs quite differently due to concurrency and due to possible amount of data
        /// that needs to pass through between processes
        /// </summary>
        public Task CalculateDiagnosticsAsync(PinnedSolutionInfo solutionInfo, DiagnosticArguments arguments, string pipeName, CancellationToken cancellationToken)
        {
            return(RunServiceAsync(async() =>
            {
                using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_CalculateDiagnosticsAsync, arguments.ProjectId.DebugName, cancellationToken))
                    using (arguments.IsHighPriority ? UserOperationBooster.Boost() : default)
                    {
                        var solution = await GetSolutionAsync(solutionInfo, cancellationToken).ConfigureAwait(false);

                        var documentId = arguments.DocumentId;
                        var projectId = arguments.ProjectId;
                        var project = solution.GetProject(projectId);
                        var documentSpan = arguments.DocumentSpan;
                        var documentAnalysisKind = arguments.DocumentAnalysisKind;
                        var diagnosticComputer = new DiagnosticComputer(documentId, project, documentSpan, documentAnalysisKind, _analyzerInfoCache);

                        var result = await diagnosticComputer.GetDiagnosticsAsync(
                            arguments.AnalyzerIds,
                            reportSuppressedDiagnostics: arguments.ReportSuppressedDiagnostics,
                            logPerformanceInfo: arguments.LogPerformanceInfo,
                            getTelemetryInfo: arguments.GetTelemetryInfo,
                            cancellationToken).ConfigureAwait(false);

                        await RemoteEndPoint.WriteDataToNamedPipeAsync(pipeName, (result, documentAnalysisKind), (writer, data, cancellationToken) =>
                        {
                            var(diagnostics, telemetry) = DiagnosticResultSerializer.WriteDiagnosticAnalysisResults(writer, data.documentAnalysisKind, data.result, cancellationToken);

                            // save log for debugging
                            Log(TraceEventType.Information, $"diagnostics: {diagnostics}, telemetry: {telemetry}");

                            return Task.CompletedTask;
                        }, cancellationToken).ConfigureAwait(false);
                    }
            }, cancellationToken));
        }
示例#11
0
            private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync(
                RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, bool forcedAnalysis, CancellationToken cancellationToken)
            {
                var solution        = project.Solution;
                var snapshotService = solution.Workspace.Services.GetService <IRemotableDataService>();

                using var pooledObject = SharedPools.Default <Dictionary <string, DiagnosticAnalyzer> >().GetPooledObject();
                var analyzerMap = pooledObject.Object;

                analyzerMap.AppendAnalyzerMap(analyzerDriver.Analyzers.Where(a => forcedAnalysis || !a.IsOpenFileOnly(solution.Options)));
                if (analyzerMap.Count == 0)
                {
                    return(DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty);
                }

                var argument = new DiagnosticArguments(
                    forcedAnalysis, analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime,
                    project.Id, analyzerMap.Keys.ToArray());

                using var session = await client.TryCreateSessionAsync(WellKnownServiceHubServices.CodeAnalysisService, solution, callbackTarget : null, cancellationToken).ConfigureAwait(false);

                if (session == null)
                {
                    // session is not available
                    return(DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty);
                }

                return(await session.Connection.InvokeAsync(
                           nameof(IRemoteDiagnosticAnalyzerService.CalculateDiagnosticsAsync),
                           new object[] { argument },
                           (stream, cancellationToken) => ReadCompilerAnalysisResultAsync(stream, analyzerMap, project, cancellationToken), cancellationToken).ConfigureAwait(false));
            }
            private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync(
                RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, bool forcedAnalysis, CancellationToken cancellationToken)
            {
                var solution        = project.Solution;
                var snapshotService = solution.Workspace.Services.GetService <IRemotableDataService>();

                using (var pooledObject = SharedPools.Default <Dictionary <string, DiagnosticAnalyzer> >().GetPooledObject())
                {
                    var analyzerMap = pooledObject.Object;

                    analyzerMap.AppendAnalyzerMap(analyzerDriver.Analyzers.Where(a => !a.IsInProcessOnly() && (forcedAnalysis || !a.IsOpenFileOnly(solution.Workspace))));
                    if (analyzerMap.Count == 0)
                    {
                        return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty));
                    }

                    var optionAsset = GetOptionsAsset(solution, project.Language, cancellationToken);

                    var argument = new DiagnosticArguments(
                        forcedAnalysis, analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime,
                        project.Id, optionAsset.Checksum, analyzerMap.Keys.ToArray());

                    using (var session = await client.TryCreateCodeAnalysisSessionAsync(solution, cancellationToken).ConfigureAwait(false))
                    {
                        if (session == null)
                        {
                            // session is not available
                            return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty));
                        }

                        session.AddAdditionalAssets(optionAsset);

                        var result = await session.InvokeAsync(
                            nameof(IRemoteDiagnosticAnalyzerService.CalculateDiagnosticsAsync),
                            new object[] { argument },
                            (s, c) => GetCompilerAnalysisResultAsync(s, analyzerMap, project, c), cancellationToken).ConfigureAwait(false);

                        ReportAnalyzerExceptions(project, result.Exceptions);

                        return(result);
                    }
                }
            }
示例#13
0
            private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync(
                RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, CancellationToken cancellationToken)
            {
                var solution        = project.Solution;
                var snapshotService = solution.Workspace.Services.GetService <ISolutionSynchronizationService>();

                // TODO: this should be moved out
                var analyzerMap = CreateAnalyzerMap(analyzerDriver.Analyzers);

                if (analyzerMap.Count == 0)
                {
                    return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty));
                }

                var optionAsset = GetOptionsAsset(solution, project.Language, cancellationToken);

                var argument = new DiagnosticArguments(
                    analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics,
                    analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime,
                    project.Id, optionAsset.Checksum, analyzerMap.Keys.ToArray());

                using (var session = await client.TryCreateCodeAnalysisServiceSessionAsync(solution, cancellationToken).ConfigureAwait(false))
                {
                    if (session == null)
                    {
                        // session is not available
                        return(DiagnosticAnalysisResultMap.Create(ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty, ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Empty));
                    }

                    session.AddAdditionalAssets(optionAsset);

                    var result = await session.InvokeAsync(
                        WellKnownServiceHubServices.CodeAnalysisService_CalculateDiagnosticsAsync,
                        new object[] { argument },
                        (s, c) => GetCompilerAnalysisResultAsync(s, analyzerMap, project, c)).ConfigureAwait(false);

                    ReportAnalyzerExceptions(project, result.Exceptions);

                    return(result);
                }
            }