Exemplo n.º 1
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));
        }
Exemplo n.º 3
0
        /// <summary>
        /// This is top level entry point for DesignerAttribute service from client (VS).
        ///
        /// This will be called by ServiceHub/JsonRpc framework
        /// </summary>
        public async Task <DesignerAttributeResult> ScanDesignerAttributesAsync(DocumentId documentId)
        {
            using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetTodoCommentsAsync, documentId.ProjectId.DebugName, CancellationToken))
            {
                try
                {
                    var solution = await GetSolutionAsync().ConfigureAwait(false);

                    var document = solution.GetDocument(documentId);

                    var service = document.GetLanguageService <IDesignerAttributeService>();
                    if (service != null)
                    {
                        // todo comment service supported
                        return(await service.ScanDesignerAttributesAsync(document, CancellationToken).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
                }

                return(new DesignerAttributeResult(designerAttributeArgument: null, containsErrors: true, notApplicable: true));
            }
        }
Exemplo n.º 4
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));
        }
Exemplo n.º 5
0
        public async Task SynchronizeGlobalAssetsAsync(Checksum[] checksums)
        {
            using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizeGlobalAssetsAsync, Checksum.GetChecksumsLogInfo, checksums, CancellationToken))
            {
                try
                {
                    var assets = await RoslynServices.AssetService.GetAssetsAsync <object>(checksums, CancellationToken).ConfigureAwait(false);

                    foreach (var asset in assets)
                    {
                        AssetStorage.TryAddGlobalAsset(asset.Item1, asset.Item2);
                    }
                }
                catch (IOException)
                {
                    // stream to send over assets has closed before we
                    // had chance to check cancellation
                }
                catch (OperationCanceledException)
                {
                    // rpc connection has closed.
                    // this can happen if client side cancelled the
                    // operation
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// This is top level entry point for TodoComments service from client (VS).
        ///
        /// This will be called by ServiceHub/JsonRpc framework
        /// </summary>
        public async Task <IList <TodoComment> > GetTodoCommentsAsync(DocumentId documentId, ImmutableArray <TodoCommentDescriptor> tokens)
        {
            using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetTodoCommentsAsync, documentId.ProjectId.DebugName, CancellationToken))
            {
                try
                {
                    var solution = await GetSolutionAsync().ConfigureAwait(false);

                    var document = solution.GetDocument(documentId);

                    var service = document.GetLanguageService <ITodoCommentService>();
                    if (service != null)
                    {
                        // todo comment service supported
                        return(await service.GetTodoCommentsAsync(document, tokens, CancellationToken).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
                }

                return(SpecializedCollections.EmptyList <TodoComment>());
            }
        }
Exemplo n.º 7
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));
        }
Exemplo n.º 8
0
 public async Task SynchronizePrimaryWorkspaceAsync(Checksum checksum, CancellationToken cancellationToken)
 {
     using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizePrimaryWorkspaceAsync, Checksum.GetChecksumLogInfo, checksum, cancellationToken))
     {
         var solutionController = (ISolutionController)RoslynServices.SolutionService;
         await solutionController.UpdatePrimaryWorkspaceAsync(checksum, cancellationToken).ConfigureAwait(false);
     }
 }
Exemplo n.º 9
0
 public override async Task <IList <(Checksum, object)> > RequestAssetsAsync(int scopeId, ISet <Checksum> checksums, CancellationToken cancellationToken)
 {
     using (RoslynLogger.LogBlock(FunctionId.SnapshotService_RequestAssetAsync, GetRequestLogInfo, scopeId, checksums, cancellationToken))
     {
         return(await _owner.Rpc.InvokeAsync(WellKnownServiceHubServices.AssetService_RequestAssetAsync,
                                             new object[] { scopeId, checksums.ToArray() },
                                             (s, c) => ReadAssets(s, scopeId, checksums, c), cancellationToken).ConfigureAwait(false));
     }
 }
Exemplo n.º 10
0
 public override async Task <bool> IsExperimentEnabledAsync(string experimentName, CancellationToken cancellationToken)
 {
     using (RoslynLogger.LogBlock(FunctionId.SnapshotService_IsExperimentEnabledAsync, experimentName, cancellationToken))
     {
         return(await _owner.RunServiceAsync(() =>
         {
             return _owner.InvokeAsync <bool>(WellKnownServiceHubServices.AssetService_IsExperimentEnabledAsync,
                                              new object[] { experimentName }, cancellationToken);
         }, cancellationToken).ConfigureAwait(false));
     }
 }
Exemplo n.º 11
0
 public Task SynchronizePrimaryWorkspaceAsync(PinnedSolutionInfo solutionInfo, Checksum checksum, int workspaceVersion, CancellationToken cancellationToken)
 {
     return(RunServiceAsync(async() =>
     {
         using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizePrimaryWorkspaceAsync, Checksum.GetChecksumLogInfo, checksum, cancellationToken))
         {
             var solutionService = CreateSolutionService(solutionInfo);
             await solutionService.UpdatePrimaryWorkspaceAsync(checksum, workspaceVersion, cancellationToken).ConfigureAwait(false);
         }
     }, cancellationToken));
 }
Exemplo n.º 12
0
        public async Task SynchronizeGlobalAssetsAsync(Checksum[] checksums, CancellationToken cancellationToken)
        {
            using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizeGlobalAssetsAsync, Checksum.GetChecksumsLogInfo, checksums, cancellationToken))
            {
                var assets = await RoslynServices.AssetService.GetAssetsAsync <object>(checksums, cancellationToken).ConfigureAwait(false);

                foreach (var asset in assets)
                {
                    AssetStorage.TryAddGlobalAsset(asset.Item1, asset.Item2);
                }
            }
        }
Exemplo n.º 13
0
        private async Task SerializeDiagnosticResultAsync(string streamName, DiagnosticAnalysisResultMap <string, DiagnosticAnalysisResultBuilder> result)
        {
            using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_SerializeDiagnosticResultAsync, GetResultLogInfo, result, CancellationToken))
                using (var stream = await DirectStream.GetAsync(streamName, CancellationToken).ConfigureAwait(false))
                {
                    using (var writer = new StreamObjectWriter(stream))
                    {
                        DiagnosticResultSerializer.Serialize(writer, result, CancellationToken);
                    }

                    await stream.FlushAsync(CancellationToken).ConfigureAwait(false);
                }
        }
        /// <summary>
        /// This is top level entry point for DesignerAttribute service from client (VS).
        ///
        /// This will be called by ServiceHub/JsonRpc framework
        /// </summary>
        public async Task <ImmutableArray <DesignerAttributeDocumentData> > ScanDesignerAttributesAsync(ProjectId projectId)
        {
            using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetDesignerAttributesAsync, projectId.DebugName, CancellationToken))
            {
                var solution = await GetSolutionAsync().ConfigureAwait(false);

                var project = solution.GetProject(projectId);
                var data    = await AbstractDesignerAttributeService.TryAnalyzeProjectInCurrentProcessAsync(
                    project, CancellationToken).ConfigureAwait(false);

                return(data.Values.ToImmutableArray());
            }
        }
Exemplo n.º 15
0
 public override async Task <IList <(Checksum, object)> > RequestAssetsAsync(int scopeId, ISet <Checksum> checksums, ISerializerService serializerService, CancellationToken cancellationToken)
 {
     return(await _owner.RunServiceAsync(() =>
     {
         using (RoslynLogger.LogBlock(FunctionId.SnapshotService_RequestAssetAsync, GetRequestLogInfo, scopeId, checksums, cancellationToken))
         {
             return _owner.EndPoint.InvokeAsync(
                 WellKnownServiceHubServices.AssetService_RequestAssetAsync,
                 new object[] { scopeId, checksums.ToArray() },
                 (stream, cancellationToken) => Task.FromResult(ReadAssets(stream, scopeId, checksums, serializerService, cancellationToken)),
                 cancellationToken);
         }
     }, cancellationToken).ConfigureAwait(false));
 }
Exemplo n.º 16
0
        public Task SynchronizeGlobalAssetsAsync(PinnedSolutionInfo solutionInfo, Checksum[] checksums, CancellationToken cancellationToken)
        {
            return(RunServiceAsync(async() =>
            {
                using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizeGlobalAssetsAsync, Checksum.GetChecksumsLogInfo, checksums, cancellationToken))
                {
                    var assetProvider = SolutionService.CreateAssetProvider(solutionInfo, AssetStorage);
                    var assets = await assetProvider.GetAssetsAsync <object>(checksums, cancellationToken).ConfigureAwait(false);

                    foreach (var(checksum, value) in assets)
                    {
                        AssetStorage.TryAddGlobalAsset(checksum, value);
                    }
                }
            }, cancellationToken));
        }
Exemplo n.º 17
0
        private async Task SerializeDiagnosticResultAsync(string streamName, DiagnosticAnalysisResultMap <string, DiagnosticAnalysisResultBuilder> result, CancellationToken cancellationToken)
        {
            using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_SerializeDiagnosticResultAsync, GetResultLogInfo, result, cancellationToken))
                using (var stream = await DirectStream.GetAsync(streamName, cancellationToken).ConfigureAwait(false))
                {
                    using (var writer = new ObjectWriter(stream))
                    {
                        var info = DiagnosticResultSerializer.Serialize(writer, result, cancellationToken);

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

                    await stream.FlushAsync(cancellationToken).ConfigureAwait(false);
                }
        }
        /// <summary>
        /// This is top level entry point for TodoComments service from client (VS).
        ///
        /// This will be called by ServiceHub/JsonRpc framework
        /// </summary>
        public async Task <IList <TodoComment> > GetTodoCommentsAsync(DocumentId documentId, ImmutableArray <TodoCommentDescriptor> tokens, CancellationToken cancellationToken)
        {
            using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetTodoCommentsAsync, documentId.ProjectId.DebugName, cancellationToken))
            {
                var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);

                var document = solution.GetDocument(documentId);

                var service = document.GetLanguageService <ITodoCommentService>();
                if (service != null)
                {
                    // todo comment service supported
                    return(await service.GetTodoCommentsAsync(document, tokens, cancellationToken).ConfigureAwait(false));
                }

                return(SpecializedCollections.EmptyList <TodoComment>());
            }
        }
        public void ReportAnalyzerPerformance(List <AnalyzerPerformanceInfo> snapshot, int unitCount, CancellationToken cancellationToken)
        {
            RunService(() =>
            {
                using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_ReportAnalyzerPerformance, cancellationToken))
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var service = SolutionService.PrimaryWorkspace.Services.GetService <IPerformanceTrackerService>();
                    if (service == null)
                    {
                        return;
                    }

                    service.AddSnapshot(snapshot, unitCount);
                }
            }, cancellationToken);
        }
 public override async Task <IList <(Checksum, object)> > RequestAssetsAsync(int scopeId, ISet <Checksum> checksums, ISerializerService serializerService, CancellationToken callerCancellation)
 {
     using (RoslynLogger.LogBlock(FunctionId.SnapshotService_RequestAssetAsync, GetRequestLogInfo, scopeId, checksums, callerCancellation))
     {
         try
         {
             return(await _owner.RunServiceAsync(cancellationToken =>
             {
                 return _owner.InvokeAsync(WellKnownServiceHubServices.AssetService_RequestAssetAsync,
                                           new object[] { scopeId, checksums.ToArray() },
                                           (s, c) => ReadAssets(s, scopeId, checksums, serializerService, c), cancellationToken);
             }, callerCancellation).ConfigureAwait(false));
         }
         catch (Exception ex) when(ReportUnlessCanceled(ex, callerCancellation))
         {
             throw ExceptionUtilities.Unreachable;
         }
     }
 }
        /// <summary>
        /// This is top level entry point for DesignerAttribute service from client (VS).
        ///
        /// This will be called by ServiceHub/JsonRpc framework
        /// </summary>
        public async Task <IList <DesignerAttributeDocumentData> > ScanDesignerAttributesAsync(ProjectId projectId, CancellationToken cancellationToken)
        {
            using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetDesignerAttributesAsync, projectId.DebugName, cancellationToken))
            {
                var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);

                var project = solution.GetProject(projectId);

                var data = await AbstractDesignerAttributeService.TryAnalyzeProjectInCurrentProcessAsync(
                    project, cancellationToken).ConfigureAwait(false);

                if (data.Count == 0)
                {
                    return(SpecializedCollections.EmptyList <DesignerAttributeDocumentData>());
                }

                return(data.Values.ToList());
            }
        }
Exemplo n.º 22
0
            public override async Task <IList <ValueTuple <Checksum, object> > > RequestAssetsAsync(int sessionId, ISet <Checksum> checksums, CancellationToken callerCancellationToken)
            {
                // it should succeed as long as matching VS is alive
                // TODO: add logging mechanism using Logger

                // this can be called in two ways.
                // 1. Connection to get asset is closed (the asset source we were using is disconnected - _assetChannelCancellationToken)
                //    if this asset source's channel is closed, service will move to next asset source to get the asset as long as callerCancellationToken
                //    is not cancelled
                //
                // 2. Request to required this asset has cancelled. (callerCancellationToken)
                using (var mergedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(_owner.CancellationToken, callerCancellationToken))
                    using (RoslynLogger.LogBlock(FunctionId.SnapshotService_RequestAssetAsync, GetRequestLogInfo, sessionId, checksums, mergedCancellationToken.Token))
                    {
                        return(await _owner.Rpc.InvokeAsync(WellKnownServiceHubServices.AssetService_RequestAssetAsync,
                                                            new object[] { sessionId, checksums.ToArray() },
                                                            (s, c) => ReadAssets(s, sessionId, checksums, c), mergedCancellationToken.Token).ConfigureAwait(false));
                    }
            }
        /// <summary>
        /// This is top level entry point for DesignerAttribute service from client (VS).
        ///
        /// This will be called by ServiceHub/JsonRpc framework
        /// </summary>
        public Task <DesignerAttributeResult> ScanDesignerAttributesAsync(DocumentId documentId, CancellationToken cancellationToken)
        {
            return(RunServiceAsync(async() =>
            {
                using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetDesignerAttributesAsync, documentId.DebugName, cancellationToken))
                {
                    var solution = await GetSolutionAsync(cancellationToken).ConfigureAwait(false);
                    var document = solution.GetDocument(documentId);

                    var service = document.GetLanguageService <IDesignerAttributeService>();
                    if (service != null)
                    {
                        // todo comment service supported
                        return await service.ScanDesignerAttributesAsync(document, cancellationToken).ConfigureAwait(false);
                    }

                    return new DesignerAttributeResult(designerAttributeArgument: null, containsErrors: true, applicable: false);
                }
            }, cancellationToken));
        }
            protected override async Task ExecuteAsync()
            {
                // wait for global operation such as build
                await GlobalOperationTask.ConfigureAwait(false);

                using (var pooledObject = SharedPools.Default <List <ExpensiveAnalyzerInfo> >().GetPooledObject())
                    using (RoslynLogger.LogBlock(FunctionId.Diagnostics_GeneratePerformaceReport, CancellationToken))
                    {
                        _diagnosticAnalyzerPerformanceTracker.GenerateReport(pooledObject.Object);

                        foreach (var analyzerInfo in pooledObject.Object)
                        {
                            var newAnalyzer = _reported.Add(analyzerInfo.AnalyzerId);

                            var isInternalUser = _telemetrySession.IsUserMicrosoftInternal;

                            // we only report same analyzer once unless it is internal user
                            if (isInternalUser || newAnalyzer)
                            {
                                // this will report telemetry under VS. this will let us see how accurate our performance tracking is
                                RoslynLogger.Log(FunctionId.Diagnostics_BadAnalyzer, KeyValueLogMessage.Create(m =>
                                {
                                    // since it is telemetry, we hash analyzer name if it is not builtin analyzer
                                    m[nameof(analyzerInfo.AnalyzerId)]                = isInternalUser ? analyzerInfo.AnalyzerId : analyzerInfo.PIISafeAnalyzerId;
                                    m[nameof(analyzerInfo.LocalOutlierFactor)]        = analyzerInfo.LocalOutlierFactor;
                                    m[nameof(analyzerInfo.Average)]                   = analyzerInfo.Average;
                                    m[nameof(analyzerInfo.AdjustedStandardDeviation)] = analyzerInfo.AdjustedStandardDeviation;
                                }));
                            }

                            // for logging, we only log once. we log here so that we can ask users to provide this log to us
                            // when we want to find out VS performance issue that could be caused by analyzer
                            if (newAnalyzer)
                            {
                                _logger.TraceEvent(TraceEventType.Warning, 0,
                                                   $"Analyzer perf indicators exceeded threshold for '{analyzerInfo.AnalyzerId}' ({analyzerInfo.AnalyzerIdHash}): " +
                                                   $"LOF: {analyzerInfo.LocalOutlierFactor}, Avg: {analyzerInfo.Average}, Stddev: {analyzerInfo.AdjustedStandardDeviation}");
                            }
                        }
                    }
            }
Exemplo n.º 25
0
 public async Task SynchronizePrimaryWorkspaceAsync(Checksum checksum)
 {
     using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_Synchronize, c => c.ToString(), checksum, CancellationToken))
     {
         try
         {
             await RoslynServices.SolutionService.UpdatePrimaryWorkspaceAsync(checksum, CancellationToken).ConfigureAwait(false);
         }
         catch (IOException)
         {
             // stream to send over assets has closed before we
             // had chance to check cancellation
         }
         catch (OperationCanceledException)
         {
             // rpc connection has closed.
             // this can happen if client side cancelled the
             // operation
         }
     }
 }
Exemplo n.º 26
0
        public async Task SynchronizeAsync(byte[] solutionChecksum)
        {
            var checksum = new Checksum(solutionChecksum);

            using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_Synchronize, c => c.ToString(), checksum, CancellationToken))
            {
                try
                {
                    // cause all assets belong to the given solution to sync to remote host
                    await RoslynServices.AssetService.SynchronizeSolutionAssetsAsync(checksum, CancellationToken).ConfigureAwait(false);
                }
                catch (IOException)
                {
                    // stream to send over assets has closed before we
                    // had chance to check cancellation
                }
                catch (OperationCanceledException)
                {
                    // rpc connection has closed.
                    // this can happen if client side cancelled the
                    // operation
                }
            }
        }
Exemplo n.º 27
0
        public Task SynchronizeTextAsync(DocumentId documentId, Checksum baseTextChecksum, IEnumerable <TextChange> textChanges, CancellationToken cancellationToken)
        {
            return(RunServiceAsync(async() =>
            {
                using (RoslynLogger.LogBlock(FunctionId.RemoteHostService_SynchronizeTextAsync, Checksum.GetChecksumLogInfo, baseTextChecksum, cancellationToken))
                {
                    var service = SolutionService.PrimaryWorkspace.Services.GetService <ISerializerService>();
                    if (service == null)
                    {
                        return;
                    }

                    var text = await TryGetSourceTextAsync().ConfigureAwait(false);
                    if (text == null)
                    {
                        // it won't bring in base text if it is not there already.
                        // text needed will be pulled in when there is request
                        return;
                    }

                    var newText = new WrappedText(text.WithChanges(textChanges));
                    var newChecksum = service.CreateChecksum(newText, cancellationToken);

                    // save new text in the cache so that when asked, the data is most likely already there
                    //
                    // this cache is very short live. and new text created above is ChangedText which share
                    // text data with original text except the changes.
                    // so memory wise, this doesn't put too much pressure on the cache. it will not duplicates
                    // same text multiple times.
                    //
                    // also, once the changes are picked up and put into Workspace, normal Workspace
                    // caching logic will take care of the text
                    AssetStorage.TryAddAsset(newChecksum, newText);
                }

                async Task <SourceText?> TryGetSourceTextAsync()
                {
                    // check the cheap and fast one first.
                    // see if the cache has the source text
                    if (AssetStorage.TryGetAsset <SourceText>(baseTextChecksum, out var sourceText))
                    {
                        return sourceText;
                    }

                    // do slower one
                    // check whether existing solution has it
                    var document = SolutionService.PrimaryWorkspace.CurrentSolution.GetDocument(documentId);
                    if (document == null)
                    {
                        return null;
                    }

                    // check checksum whether it is there.
                    // since we lazily synchronize whole solution (SynchronizePrimaryWorkspaceAsync) when things are idle,
                    // soon or later this will get hit even if text changes got out of sync due to issues in VS side
                    // such as file is first opened and there is no SourceText in memory yet.
                    if (!document.State.TryGetStateChecksums(out var state) ||
                        !state.Text.Equals(baseTextChecksum))
                    {
                        return null;
                    }

                    return await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
                }
            }, cancellationToken));
        }