Esempio n. 1
0
        private static string LogSynchronizeWithBuild(OptionSet options, ImmutableDictionary <ProjectId, ImmutableArray <DiagnosticData> > map)
        {
            using var pooledObject = SharedPools.Default <StringBuilder>().GetPooledObject();
            var sb = pooledObject.Object;

            sb.Append($"PreferBuildError:{PreferBuildErrors(options)}, PreferLiveOnOpenFiles:{PreferLiveErrorsOnOpenedFiles(options)}");

            if (map.Count > 0)
            {
                foreach (var(projectId, diagnostics) in map)
                {
                    sb.AppendLine($"{projectId}, Count: {diagnostics.Length}");

                    foreach (var diagnostic in diagnostics)
                    {
                        sb.AppendLine($"    {diagnostic.ToString()}");
                    }
                }
            }

            return(sb.ToString());
        }
Esempio n. 2
0
            public async Task <FirstDiagnosticResult> GetFirstDiagnosticWithFixAsync(Document document, TextSpan range, bool considerSuppressionFixes, CancellationToken cancellationToken)
            {
                if (document == null || !document.IsOpen())
                {
                    return(default(FirstDiagnosticResult));
                }

                using (var diagnostics = SharedPools.Default <List <DiagnosticData> >().GetPooledObject())
                {
                    var fullResult = await _diagnosticService.TryAppendDiagnosticsForSpanAsync(document, range, diagnostics.Object, cancellationToken : cancellationToken).ConfigureAwait(false);

                    foreach (var diagnostic in diagnostics.Object)
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        if (!range.IntersectsWith(diagnostic.TextSpan))
                        {
                            continue;
                        }

                        // REVIEW: 2 possible designs.
                        // 1. find the first fix and then return right away. if the lightbulb is actually expanded, find all fixes for the line synchronously. or
                        // 2. kick off a task that finds all fixes for the given range here but return once we find the first one.
                        // at the same time, let the task to run to finish. if the lightbulb is expanded, we just simply use the task to get all fixes.
                        //
                        // first approach is simpler, so I will implement that first. if the first approach turns out to be not good enough, then
                        // I will try the second approach which will be more complex but quicker
                        var hasFix = await ContainsAnyFix(document, diagnostic, considerSuppressionFixes, cancellationToken).ConfigureAwait(false);

                        if (hasFix)
                        {
                            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                            return(new FirstDiagnosticResult(!fullResult, hasFix, diagnostic));
                        }
                    }

                    return(new FirstDiagnosticResult(!fullResult, false, default(DiagnosticData)));
                }
            }
        private SyntaxNode CreateFormattedRoot(CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.Formatting_CreateFormattedRoot, cancellationToken))
            {
                var changes = GetChanges(cancellationToken);

                // create a map
                using (var pooledObject = SharedPools.Default <Dictionary <ValueTuple <SyntaxToken, SyntaxToken>, TriviaData> >().GetPooledObject())
                {
                    var map = pooledObject.Object;
                    changes.Do(change => map.Add(change.Item1, change.Item2));

                    // no changes, return as it is.
                    if (map.Count == 0)
                    {
                        return(this.TreeInfo.Root);
                    }

                    return(Rewriter(map, cancellationToken));
                }
            }
        }
Esempio n. 4
0
        private IEnumerable <CompletionItem> CreateCompletionItems(
            Workspace workspace, SemanticModel semanticModel, IEnumerable <ISymbol> symbols, SyntaxToken token, TextSpan itemSpan, int position, ImmutableDictionary <string, string> options)
        {
            var builder = SharedPools.Default <StringBuilder>().Allocate();

            try
            {
                foreach (var symbol in symbols)
                {
                    yield return(CreateItem(workspace, semanticModel, symbol, token, position, builder, options));

                    if (TryCreateSpecialTypeItem(workspace, semanticModel, symbol, token, position, builder, options, out var item))
                    {
                        yield return(item);
                    }
                }
            }
            finally
            {
                SharedPools.Default <StringBuilder>().ClearAndFree(builder);
            }
        }
Esempio n. 5
0
        private static void ApplyChanges(
            IProjectionBuffer subjectBuffer,
            IEnumerable <TextChange> changes,
            IList <TextSpan> visibleSpansInOriginal,
            out IEnumerable <int> affectedVisibleSpansInNew)
        {
            using var edit = subjectBuffer.CreateEdit(s_venusEditOptions, reiteratedVersionNumber: null, editTag: null);

            var affectedSpans = SharedPools.Default <HashSet <int> >().AllocateAndClear();

            affectedVisibleSpansInNew = affectedSpans;

            var currentVisibleSpanIndex = 0;

            foreach (var change in changes)
            {
                // Find the next visible span that either overlaps or intersects with
                while (currentVisibleSpanIndex < visibleSpansInOriginal.Count &&
                       visibleSpansInOriginal[currentVisibleSpanIndex].End < change.Span.Start)
                {
                    currentVisibleSpanIndex++;
                }

                // no more place to apply text changes
                if (currentVisibleSpanIndex >= visibleSpansInOriginal.Count)
                {
                    break;
                }

                var newText = change.NewText;
                var span    = change.Span.ToSpan();

                edit.Replace(span, newText);

                affectedSpans.Add(currentVisibleSpanIndex);
            }

            edit.ApplyAndLogExceptions();
        }
Esempio n. 6
0
        private static string LogSynchronizeWithBuild(Workspace workspace, ImmutableDictionary <ProjectId, ImmutableArray <DiagnosticData> > map)
        {
            using var pooledObject = SharedPools.Default <StringBuilder>().GetPooledObject();
            var sb = pooledObject.Object;

            sb.Append($"PreferBuildError:{PreferBuildErrors(workspace)}, PreferLiveOnOpenFiles:{PreferLiveErrorsOnOpenedFiles(workspace)}");

            if (map.Count > 0)
            {
                foreach (var kv in map)
                {
                    sb.AppendLine($"{kv.Key}, Count: {kv.Value.Length}");

                    foreach (var diagnostic in kv.Value)
                    {
                        sb.AppendLine($"    {diagnostic.ToString()}");
                    }
                }
            }

            return(sb.ToString());
        }
            private async Task <IEnumerable <Diagnostic> > ComputeProjectDiagnosticAnalyzerDiagnosticsAsync(
                Project project, ProjectDiagnosticAnalyzer analyzer, Compilation compilationOpt, CancellationToken cancellationToken)
            {
                using (var pooledObject = SharedPools.Default <List <Diagnostic> >().GetPooledObject())
                {
                    var diagnostics = pooledObject.Object;
                    cancellationToken.ThrowIfCancellationRequested();

                    try
                    {
                        await analyzer.AnalyzeProjectAsync(project, diagnostics.Add, cancellationToken).ConfigureAwait(false);

                        // REVIEW: V1 doesn't convert diagnostics to effective diagnostics. not sure why.
                        return(compilationOpt == null?diagnostics.ToImmutableArrayOrEmpty() : CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilationOpt));
                    }
                    catch (Exception e) when(!IsCanceled(e, cancellationToken))
                    {
                        OnAnalyzerException(analyzer, project.Id, compilationOpt, e);
                        return(ImmutableArray <Diagnostic> .Empty);
                    }
                }
            }
Esempio n. 8
0
        private ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> CreateAnalysisResults(
            Project project, ImmutableArray <StateSet> stateSets, ProjectAnalysisData oldAnalysisData, ImmutableArray <DiagnosticData> diagnostics)
        {
            using var poolObject = SharedPools.Default <HashSet <string> >().GetPooledObject();

            var lookup = diagnostics.ToLookup(d => d.Id);

            var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, DiagnosticAnalysisResult>();

            foreach (var stateSet in stateSets)
            {
                var descriptors = DiagnosticAnalyzerInfoCache.GetDiagnosticDescriptors(stateSet.Analyzer);

                var liveDiagnostics = MergeDiagnostics(
                    ConvertToLiveDiagnostics(lookup, descriptors, poolObject.Object),
                    oldAnalysisData.GetResult(stateSet.Analyzer).GetAllDiagnostics());

                builder.Add(stateSet.Analyzer, DiagnosticAnalysisResult.CreateFromBuild(project, liveDiagnostics));
            }

            return(builder.ToImmutable());
        }
        public List <ILexerRule> GetExpectedLexerRules()
        {
            var list = SharedPools.Default <List <ILexerRule> >().AllocateAndClear();

            if (_chart.FrameSets.Count == 0)
            {
                return(list);
            }

            var frameSet = _chart.FrameSets[_chart.FrameSets.Count - 1];

            for (var i = 0; i < frameSet.Frames.Count; i++)
            {
                var stateFrame = frameSet.Frames[i];
                for (int j = 0; j < stateFrame.Frame.ScanKeys.Count; j++)
                {
                    var lexerRule = stateFrame.Frame.ScanKeys[j];
                    list.Add(lexerRule);
                }
            }
            return(list);
        }
Esempio n. 10
0
            private async Task SynchronizeAssetsAsync(
                Dictionary <ProjectId, ProjectStateChecksums> oldMap,
                Dictionary <ProjectId, ProjectStateChecksums> newMap
                )
            {
                using var pooledObject = SharedPools.Default <HashSet <Checksum> >().GetPooledObject();

                // added project
                foreach (var kv in newMap)
                {
                    if (oldMap.ContainsKey(kv.Key))
                    {
                        continue;
                    }

                    pooledObject.Object.Add(kv.Value.Checksum);
                }

                await _assetProvider
                .SynchronizeProjectAssetsAsync(pooledObject.Object, _cancellationToken)
                .ConfigureAwait(false);
            }
Esempio n. 11
0
            private Worker(
                SemanticModel semanticModel,
                TextSpan textSpan,
                ArrayBuilder <ClassifiedSpan> list,
                Func <SyntaxNode, ImmutableArray <ISyntaxClassifier> > getNodeClassifiers,
                Func <SyntaxToken, ImmutableArray <ISyntaxClassifier> > getTokenClassifiers,
                ClassificationOptions options,
                CancellationToken cancellationToken)
            {
                _getNodeClassifiers  = getNodeClassifiers;
                _getTokenClassifiers = getTokenClassifiers;
                _semanticModel       = semanticModel;
                _syntaxTree          = semanticModel.SyntaxTree;
                _textSpan            = textSpan;
                _list = list;
                _cancellationToken = cancellationToken;
                _options           = options;

                // get one from pool
                _set          = SharedPools.Default <HashSet <ClassifiedSpan> >().AllocateAndClear();
                _pendingNodes = SharedPools.Default <Stack <SyntaxNodeOrToken> >().AllocateAndClear();
            }
            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 badAnalyzerInfo in pooledObject.Object)
                        {
                            var newAnalyzer  = _reported.Add(badAnalyzerInfo.AnalyzerId);
                            var internalUser = WatsonReporter.IsUserMicrosoftInternal;

                            // we only report same analyzer once unless it is internal user
                            if (internalUser || 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(badAnalyzerInfo.AnalyzerId)]                = internalUser ? badAnalyzerInfo.AnalyzerId : badAnalyzerInfo.PIISafeAnalyzerId;
                                    m[nameof(badAnalyzerInfo.LocalOutlierFactor)]        = badAnalyzerInfo.LocalOutlierFactor;
                                    m[nameof(badAnalyzerInfo.Average)]                   = badAnalyzerInfo.Average;
                                    m[nameof(badAnalyzerInfo.AdjustedStandardDeviation)] = badAnalyzerInfo.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.Error, 0, $"[{badAnalyzerInfo.AnalyzerId} ({badAnalyzerInfo.AnalyzerIdHash})] LOF: {badAnalyzerInfo.LocalOutlierFactor}, Avg: {badAnalyzerInfo.Average}, Stddev: {badAnalyzerInfo.AdjustedStandardDeviation}");
                            }
                        }
                    }
            }
Esempio n. 13
0
            internal static void Classify(
                SemanticModel semanticModel,
                TextSpan textSpan,
                ArrayBuilder <ClassifiedSpan> list,
                Func <SyntaxNode, ImmutableArray <ISyntaxClassifier> > getNodeClassifiers,
                Func <SyntaxToken, ImmutableArray <ISyntaxClassifier> > getTokenClassifiers,
                ClassificationOptions options,
                CancellationToken cancellationToken)
            {
                var worker = new Worker(semanticModel, textSpan, list, getNodeClassifiers, getTokenClassifiers, options, cancellationToken);

                try
                {
                    worker._pendingNodes.Push(worker._syntaxTree.GetRoot(cancellationToken));
                    worker.ProcessNodes();
                }
                finally
                {
                    // release collections to the pool
                    SharedPools.Default <HashSet <ClassifiedSpan> >().ClearAndFree(worker._set);
                    SharedPools.Default <Stack <SyntaxNodeOrToken> >().ClearAndFree(worker._pendingNodes);
                }
            }
Esempio n. 14
0
        private BidirectionalMap <string, DiagnosticAnalyzer> CreateAnalyzerMap(IEnumerable <AnalyzerReference> hostAnalyzers, Project project)
        {
            // we could consider creating a service so that we don't do this repeatedly if this shows up as perf cost
            using var pooledObject = SharedPools.Default <HashSet <object> >().GetPooledObject();
            using var pooledMap    = SharedPools.Default <Dictionary <string, DiagnosticAnalyzer> >().GetPooledObject();
            var referenceSet = pooledObject.Object;
            var analyzerMap  = pooledMap.Object;

            // this follow what we do in DiagnosticAnalyzerInfoCache.CheckAnalyzerReferenceIdentity
            foreach (var reference in hostAnalyzers.Concat(project.AnalyzerReferences))
            {
                if (!referenceSet.Add(reference.Id))
                {
                    // already exist
                    continue;
                }

                analyzerMap.AppendAnalyzerMap(reference.GetAnalyzers(project.Language));
            }

            // convert regular map to bidirectional map
            return(new BidirectionalMap <string, DiagnosticAnalyzer>(analyzerMap));
        }
Esempio n. 15
0
        private void RaiseDiagnosticsCleared(IDiagnosticUpdateSource source)
        {
            var ev = _eventMap.GetEventHandlers <EventHandler <DiagnosticsUpdatedArgs> >(DiagnosticsUpdatedEventName);

            _eventQueue.ScheduleTask(DiagnosticsUpdatedEventName, () =>
            {
                using var pooledObject = SharedPools.Default <List <DiagnosticsUpdatedArgs> >().GetPooledObject();

                var removed = pooledObject.Object;
                if (!ClearDiagnosticsReportedBySource(source, removed))
                {
                    // there is no change, nothing to raise events for.
                    return;
                }

                // don't create event listener if it haven't created yet. if there is a diagnostic to remove
                // listener should have already created since all events are done in the serialized queue
                foreach (var args in removed)
                {
                    ev.RaiseEvent(handler => handler(source, args));
                }
            }, CancellationToken.None);
        }
Esempio n. 16
0
            internal static void Classify(
                Workspace workspace,
                SemanticModel semanticModel,
                TextSpan textSpan,
                List <ClassifiedSpan> list,
                Func <SyntaxNode, List <ISyntaxClassifier> > getNodeClassifiers,
                Func <SyntaxToken, List <ISyntaxClassifier> > getTokenClassifiers,
                CancellationToken cancellationToken)
            {
                var worker = new Worker(workspace, semanticModel, textSpan, list, getNodeClassifiers, getTokenClassifiers, cancellationToken);

                try
                {
                    worker.pendingNodes.Push(worker.syntaxTree.GetRoot(cancellationToken));
                    worker.ProcessNodes();
                }
                finally
                {
                    // release collections to the pool
                    SharedPools.Default <HashSet <ClassifiedSpan> >().ClearAndFree(worker.set);
                    SharedPools.Default <Stack <SyntaxNodeOrToken> >().ClearAndFree(worker.pendingNodes);
                }
            }
        private static string SnapshotLogger(IEnumerable <AnalyzerPerformanceInfo> snapshots, int unitCount)
        {
            using (var pooledObject = SharedPools.Default <StringBuilder>().GetPooledObject())
            {
                var sb = pooledObject.Object;

                sb.Append(unitCount);

                foreach (var snapshot in snapshots)
                {
                    sb.Append("|");
                    sb.Append(snapshot.AnalyzerId);
                    sb.Append(":");
                    sb.Append(snapshot.BuiltIn);
                    sb.Append(":");
                    sb.Append(snapshot.TimeSpan.TotalMilliseconds);
                }

                sb.Append("*");

                return(sb.ToString());
            }
        }
Esempio n. 18
0
    private bool MatchesExistingIgnoreLexemes(char character)
    {
        if (!AnyExistingIngoreLexemes())
        {
            return(false);
        }

        var            pool    = SharedPools.Default <List <ILexeme> >();
        List <ILexeme> matches = null;

        for (int i = 0; i < _ignoreLexemes.Count; i++)
        {
            var lexeme = _ignoreLexemes[i];
            if (!lexeme.Scan(character))
            {
                FreeLexeme(lexeme);
                continue;
            }
            if (matches == null)
            {
                matches = pool.AllocateAndClear();
            }
            matches.Add(lexeme);
        }

        if (matches == null)
        {
            _ignoreLexemes.Clear();
            pool.ClearAndFree(matches);
            return(false);
        }

        pool.ClearAndFree(_ignoreLexemes);
        _ignoreLexemes = matches;

        return(_ignoreLexemes.Count > 0);
    }
        private async Task SynchronizeWithBuildAsync(Document document, IEnumerable <StateSet> stateSets, IEnumerable <DiagnosticData> diagnostics)
        {
            var workspace = document.Project.Solution.Workspace;

            // check whether, for opened documents, we want to prefer live diagnostics
            if (PreferLiveErrorsOnOpenedFiles(workspace) && workspace.IsDocumentOpen(document.Id))
            {
                // enqueue re-analysis of open documents.
                this.Owner.Reanalyze(workspace, documentIds: SpecializedCollections.SingletonEnumerable(document.Id), highPriority: true);
                return;
            }

            using (var poolObject = SharedPools.Default <HashSet <string> >().GetPooledObject())
            {
                var lookup = CreateDiagnosticIdLookup(diagnostics);

                foreach (var stateSet in stateSets)
                {
                    // we are using Default so that things like LB can't use cached information
                    var textVersion     = VersionStamp.Default;
                    var semanticVersion = await document.Project.GetDependentSemanticVersionAsync(CancellationToken.None).ConfigureAwait(false);

                    // clear document and project live errors
                    await PersistAndReportAsync(stateSet, StateType.Project, document, textVersion, semanticVersion, ImmutableArray <DiagnosticData> .Empty).ConfigureAwait(false);
                    await PersistAndReportAsync(stateSet, StateType.Syntax, document, textVersion, semanticVersion, ImmutableArray <DiagnosticData> .Empty).ConfigureAwait(false);

                    var descriptors     = HostAnalyzerManager.GetDiagnosticDescriptors(stateSet.Analyzer);
                    var liveDiagnostics = ConvertToLiveDiagnostics(lookup, descriptors, poolObject.Object);

                    // REVIEW: for now, we are putting build error in document state rather than creating its own state.
                    //         reason is so that live error can take over it as soon as possible
                    //         this also means there can be slight race where it will clean up eventually. if live analysis runs for syntax but didn't run
                    //         for document yet, then we can have duplicated entries in the error list until live analysis catch.
                    await PersistAndReportAsync(stateSet, StateType.Document, document, textVersion, semanticVersion, liveDiagnostics).ConfigureAwait(false);
                }
            }
        }
Esempio n. 20
0
        private StrongBox <ImmutableArray <DiagnosticData> > ReadFrom(ObjectReader reader, Project project, Document document, CancellationToken cancellationToken)
        {
            try
            {
                using (var pooledObject = SharedPools.Default <List <DiagnosticData> >().GetPooledObject())
                {
                    var list = pooledObject.Object;

                    var format = reader.ReadInt32();
                    if (format != FormatVersion)
                    {
                        return(null);
                    }

                    // saved data is for same analyzer of different version of dll
                    var analyzerVersion = VersionStamp.ReadFrom(reader);
                    if (analyzerVersion != AnalyzerVersion)
                    {
                        return(null);
                    }

                    var version = VersionStamp.ReadFrom(reader);
                    if (version != VersionStamp.Default && version != Version)
                    {
                        return(null);
                    }

                    ReadFrom(reader, project, document, list, cancellationToken);

                    return(new StrongBox <ImmutableArray <DiagnosticData> >(list.ToImmutableArray()));
                }
            }
            catch (Exception)
            {
                return(null);
            }
        }
        private async Task SynchronizeWithBuildAsync(Project project, IEnumerable <StateSet> stateSets, IEnumerable <DiagnosticData> diagnostics)
        {
            using (var poolObject = SharedPools.Default <HashSet <string> >().GetPooledObject())
            {
                var lookup = CreateDiagnosticIdLookup(diagnostics);
                foreach (var stateSet in stateSets)
                {
                    var descriptors     = HostAnalyzerManager.GetDiagnosticDescriptors(stateSet.Analyzer);
                    var liveDiagnostics = ConvertToLiveDiagnostics(lookup, descriptors, poolObject.Object);

                    // we are using Default so that things like LB can't use cached information
                    var projectTextVersion = VersionStamp.Default;
                    var semanticVersion    = await project.GetDependentSemanticVersionAsync(CancellationToken.None).ConfigureAwait(false);

                    var state = stateSet.GetState(StateType.Project);
                    var existingDiagnostics = await state.TryGetExistingDataAsync(project, CancellationToken.None).ConfigureAwait(false);

                    var mergedDiagnostics = MergeDiagnostics(liveDiagnostics, GetExistingDiagnostics(existingDiagnostics));
                    await state.PersistAsync(project, new AnalysisData(projectTextVersion, semanticVersion, mergedDiagnostics), CancellationToken.None).ConfigureAwait(false);

                    RaiseDiagnosticsCreated(StateType.Project, project.Id, stateSet, new SolutionArgument(project), mergedDiagnostics);
                }
            }
        }
Esempio n. 22
0
        private bool TryGetSubTextChanges(
            SourceText originalText, TextSpan visibleSpanInOriginalText, string leftText, string rightText, int offsetInOriginalText, List <TextChange> changes)
        {
            // these are expensive. but hopely, we don't hit this as much except the boundary cases.
            using (var leftPool = SharedPools.Default <List <TextSpan> >().GetPooledObject())
                using (var rightPool = SharedPools.Default <List <TextSpan> >().GetPooledObject())
                {
                    var spansInLeftText  = leftPool.Object;
                    var spansInRightText = rightPool.Object;

                    if (TryGetWhitespaceOnlyChanges(leftText, rightText, spansInLeftText, spansInRightText))
                    {
                        for (var i = 0; i < spansInLeftText.Count; i++)
                        {
                            var spanInLeftText  = spansInLeftText[i];
                            var spanInRightText = spansInRightText[i];
                            if (spanInLeftText.IsEmpty && spanInRightText.IsEmpty)
                            {
                                continue;
                            }

                            var spanInOriginalText = new TextSpan(offsetInOriginalText + spanInLeftText.Start, spanInLeftText.Length);

                            TextChange textChange;
                            if (TryGetSubTextChange(originalText, visibleSpanInOriginalText, rightText, spanInOriginalText, spanInRightText, out textChange))
                            {
                                changes.Add(textChange);
                            }
                        }

                        return(true);
                    }

                    return(false);
                }
        }
Esempio n. 23
0
        public async Task <ImmutableArray <Diagnostic> > GetProjectDiagnosticsAsync(DiagnosticAnalyzer analyzer)
        {
            try
            {
                Contract.ThrowIfNull(_project);
                Contract.ThrowIfFalse(_document == null);

                using (var diagnostics = SharedPools.Default <List <Diagnostic> >().GetPooledObject())
                {
                    if (_project.SupportsCompilation)
                    {
                        await this.GetCompilationDiagnosticsAsync(analyzer, diagnostics.Object).ConfigureAwait(false);
                    }

                    await this.GetProjectDiagnosticsWorkerAsync(analyzer, diagnostics.Object).ConfigureAwait(false);

                    return(diagnostics.Object.ToImmutableArray());
                }
            }
            catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Esempio n. 24
0
    private bool MatchesExistingIncompleteIgnoreLexemes(char character)
    {
        if (!AnyExistingIngoreLexemes())
        {
            return(false);
        }

        var pool    = SharedPools.Default <List <ILexeme> >();
        var matches = pool.AllocateAndClear();

        for (var i = 0; i < _ignoreLexemes.Count; i++)
        {
            var lexeme = _ignoreLexemes[i];
            if (!lexeme.IsAccepted())
            {
                if (lexeme.Scan(character))
                {
                    matches.Add(lexeme);
                }
                else
                {
                    FreeLexeme(lexeme);
                }
            }
        }

        if (matches.Count == 0)
        {
            pool.ClearAndFree(matches);
            return(false);
        }

        pool.ClearAndFree(_ignoreLexemes);
        _ignoreLexemes = matches;
        return(true);
    }
Esempio n. 25
0
        private IEnumerable <DiagnosticData> GetDiagnostics(
            Workspace workspace, ProjectId projectId, DocumentId documentId, bool includeSuppressedDiagnostics, CancellationToken cancellationToken)
        {
            foreach (var source in _updateSources)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (source.SupportGetDiagnostics)
                {
                    foreach (var diagnostic in source.GetDiagnostics(workspace, projectId, documentId, null, includeSuppressedDiagnostics, cancellationToken))
                    {
                        AssertIfNull(diagnostic);
                        yield return(diagnostic);
                    }
                }
                else
                {
                    using (var list = SharedPools.Default <List <Data> >().GetPooledObject())
                    {
                        AppendMatchingData(source, workspace, projectId, documentId, null, list.Object);

                        foreach (var data in list.Object)
                        {
                            foreach (var diagnostic in data.Diagnostics)
                            {
                                AssertIfNull(diagnostic);
                                if (includeSuppressedDiagnostics || !diagnostic.IsSuppressed)
                                {
                                    yield return(diagnostic);
                                }
                            }
                        }
                    }
                }
            }
        }
            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);
                }

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

                ReportAnalyzerExceptions(project, result.Exceptions);

                return(result);
            }
Esempio n. 27
0
            private async Task <Project> UpdateDocumentsAsync(
                Project project,
                IEnumerable <TextDocumentState> existingTextDocumentStates,
                ChecksumCollection oldChecksums,
                ChecksumCollection newChecksums,
                Func <Solution, ImmutableArray <DocumentInfo>, Solution> addDocuments,
                Func <Solution, DocumentId, Solution> removeDocument)
            {
                using var olds = SharedPools.Default <HashSet <Checksum> >().GetPooledObject();
                using var news = SharedPools.Default <HashSet <Checksum> >().GetPooledObject();

                olds.Object.UnionWith(oldChecksums);
                news.Object.UnionWith(newChecksums);

                // remove documents that exist in both side
                olds.Object.ExceptWith(newChecksums);
                news.Object.ExceptWith(oldChecksums);

                var oldMap = await GetDocumentMapAsync(existingTextDocumentStates, olds.Object).ConfigureAwait(false);

                var newMap = await GetDocumentMapAsync(_assetProvider, news.Object).ConfigureAwait(false);

                // added document
                ImmutableArray <DocumentInfo> .Builder?lazyDocumentsToAdd = null;
                foreach (var(documentId, newDocumentChecksums) in newMap)
                {
                    if (!oldMap.ContainsKey(documentId))
                    {
                        lazyDocumentsToAdd ??= ImmutableArray.CreateBuilder <DocumentInfo>();

                        // we have new document added
                        var documentInfo = await _assetProvider.CreateDocumentInfoAsync(newDocumentChecksums.Checksum, _cancellationToken).ConfigureAwait(false);

                        lazyDocumentsToAdd.Add(documentInfo);
                    }
                }

                if (lazyDocumentsToAdd != null)
                {
                    project = addDocuments(project.Solution, lazyDocumentsToAdd.ToImmutable()).GetProject(project.Id) !;
                }

                // changed document
                foreach (var(documentId, newDocumentChecksums) in newMap)
                {
                    if (!oldMap.TryGetValue(documentId, out var oldDocumentChecksums))
                    {
                        continue;
                    }

                    Contract.ThrowIfTrue(oldDocumentChecksums.Checksum == newDocumentChecksums.Checksum);

                    var document = project.GetDocument(documentId) ?? project.GetAdditionalDocument(documentId) ?? project.GetAnalyzerConfigDocument(documentId);
                    Contract.ThrowIfNull(document);

                    project = await UpdateDocumentAsync(document, oldDocumentChecksums, newDocumentChecksums).ConfigureAwait(false);
                }

                // removed document
                foreach (var(documentId, _) in oldMap)
                {
                    if (!newMap.ContainsKey(documentId))
                    {
                        // we have a document removed
                        project = removeDocument(project.Solution, documentId).GetProject(project.Id) !;
                    }
                }

                return(project);
            }
Esempio n. 28
0
 public static List <T> Allocate()
 {
     return(SharedPools.Default <List <T> >().AllocateAndClear());
 }
Esempio n. 29
0
 public static void Free(List <T> list)
 {
     SharedPools.Default <List <T> >().ClearAndFree(list);
 }
Esempio n. 30
0
 private void DeallocateStringBuilderAndAssignCapture()
 {
     _capture = _stringBuilder.ToString();
     SharedPools.Default <StringBuilder>().ClearAndFree(_stringBuilder);
     _stringBuilder = null;
 }