Пример #1
0
        internal static async Task ParseBuffersAsync(
            PythonEditorServices services,
            VsProjectAnalyzer analyzer,
            IEnumerable <ITextSnapshot> snapshots
            )
        {
            var updates = snapshots
                          .GroupBy(s => PythonTextBufferInfo.TryGetForBuffer(s.TextBuffer)?.AnalysisEntry.FileId ?? -1)
                          .Where(g => g.Key >= 0)
                          .Select(g => Tuple.Create(
                                      g.Key,
                                      g.Select(s => GetUpdateForSnapshot(services, s)).Where(u => u != null).ToArray()
                                      ))
                          .ToList();

            if (!updates.Any())
            {
                return;
            }


            foreach (var update in updates)
            {
                if (update.Item1 < 0)
                {
                    continue;
                }

                analyzer._analysisComplete = false;
                Interlocked.Increment(ref analyzer._parsePending);

                var res = await analyzer.SendRequestAsync(
                    new AP.FileUpdateRequest()
                {
                    fileId  = update.Item1,
                    updates = update.Item2
                }
                    );

                if (res != null)
                {
                    Debug.Assert(res.failed != true);
                    analyzer.OnAnalysisStarted();
                    ValidateBufferContents(snapshots, res);
                }
                else
                {
                    Interlocked.Decrement(ref analyzer._parsePending);
                }
            }
        }
Пример #2
0
        internal static async Task ParseBuffersAsync(
            PythonEditorServices services,
            VsProjectAnalyzer analyzer,
            IEnumerable <ITextSnapshot> snapshots
            )
        {
            var tasks = new List <Tuple <ITextSnapshot[], Task <AP.FileUpdateResponse> > >();

            foreach (var snapshotGroup in snapshots.GroupBy(s => PythonTextBufferInfo.TryGetForBuffer(s.TextBuffer)))
            {
                var entry = snapshotGroup.Key?.AnalysisEntry;
                if (entry == null)
                {
                    continue;
                }

                var updates = snapshotGroup.Select(s => GetUpdateForSnapshot(snapshotGroup.Key, s)).Where(u => u != null).ToArray();
                if (!updates.Any())
                {
                    continue;
                }

                analyzer._analysisComplete = false;
                Interlocked.Increment(ref analyzer._parsePending);

                tasks.Add(Tuple.Create(snapshotGroup.ToArray(), analyzer.SendRequestAsync(
                                           new AP.FileUpdateRequest {
                    fileId  = entry.FileId,
                    updates = updates
                }
                                           )));
            }

            foreach (var task in tasks)
            {
                var res = await task.Item2;

                if (res != null)
                {
                    Debug.Assert(res.failed != true);
                    analyzer.OnAnalysisStarted();
                    ValidateBufferContents(task.Item1, res);
                }
                else
                {
                    Interlocked.Decrement(ref analyzer._parsePending);
                }
            }
        }
Пример #3
0
        private async Task ParseBuffers(ITextSnapshot[] snapshots, BufferInfo[] bufferInfos)
        {
            var           indentationSeverity = _parser.PyService.GeneralOptions.IndentationInconsistencySeverity;
            AnalysisEntry entry = AnalysisEntry;

            List <AP.FileUpdate> updates = new List <AP.FileUpdate>();

            lock (this) {
                for (int i = 0; i < snapshots.Length; i++)
                {
                    var snapshot   = snapshots[i];
                    var bufferInfo = bufferInfos[i];

                    if (snapshot.TextBuffer.Properties.ContainsProperty(DoNotParse) ||
                        snapshot.IsReplBufferWithCommand())
                    {
                        continue;
                    }

                    var lastSent = GetLastSentSnapshot(bufferInfo.Buffer);
                    if (lastSent == null || lastSent.TextBuffer != snapshot.TextBuffer)
                    {
                        // First time parsing from a live buffer, send the entire
                        // file and set our initial snapshot.  We'll roll forward
                        // to new snapshots when we receive the errors event.  This
                        // just makes sure that the content is in sync.
                        updates.Add(
                            new AP.FileUpdate()
                        {
                            content  = snapshot.GetText(),
                            version  = snapshot.Version.VersionNumber,
                            bufferId = bufferInfo.Id,
                            kind     = AP.FileUpdateKind.reset
                        }
                            );
                    }
                    else
                    {
                        if (lastSent.Version == snapshot.Version)
                        {
                            // this snapshot is up to date...
                            continue;
                        }

                        List <AP.VersionChanges> versions = new List <AnalysisProtocol.VersionChanges>();
                        for (var curVersion = lastSent.Version;
                             curVersion != snapshot.Version;
                             curVersion = curVersion.Next)
                        {
                            versions.Add(
                                new AP.VersionChanges()
                            {
                                changes = GetChanges(curVersion)
                            }
                                );
                        }

                        updates.Add(
                            new AP.FileUpdate()
                        {
                            versions = versions.ToArray(),
                            version  = snapshot.Version.VersionNumber,
                            bufferId = bufferInfo.Id,
                            kind     = AP.FileUpdateKind.changes
                        }
                            );
                    }

                    Debug.WriteLine("Added parse request {0}", snapshot.Version.VersionNumber);
                    entry.AnalysisCookie = new SnapshotCookie(snapshot);  // TODO: What about multiple snapshots?
                    SetLastSentSnapshot(snapshot);
                }
            }

            if (updates.Count != 0)
            {
                _parser._analysisComplete = false;
                Interlocked.Increment(ref _parser._parsePending);

                var res = await _parser.SendRequestAsync(
                    new AP.FileUpdateRequest()
                {
                    fileId  = entry.FileId,
                    updates = updates.ToArray()
                }
                    );

                if (res != null)
                {
                    Debug.Assert(res.failed != true);
                    _parser.OnAnalysisStarted();
#if DEBUG
                    for (int i = 0; i < bufferInfos.Length; i++)
                    {
                        var snapshot = snapshots[i];
                        var buffer   = bufferInfos[i];

                        string newCode;
                        if (res.newCode.TryGetValue(buffer.Id, out newCode))
                        {
                            Debug.Assert(newCode == snapshot.GetText(), "Buffer content mismatch - safe to ignore");
                        }
                    }
#endif
                }
                else
                {
                    Interlocked.Decrement(ref _parser._parsePending);
                }
            }
        }
Пример #4
0
        internal static async Task ParseBuffersAsync(
            PythonEditorServices services,
            VsProjectAnalyzer analyzer,
            IEnumerable <ITextSnapshot> snapshots,
            bool retryOnFailure
            )
        {
            var tasks = new List <Tuple <ITextSnapshot[], Task <AP.FileUpdateResponse> > >();

            foreach (var snapshotGroup in snapshots.GroupBy(s => PythonTextBufferInfo.TryGetForBuffer(s.TextBuffer)))
            {
                var entry = snapshotGroup.Key?.AnalysisEntry;
                if (entry == null)
                {
                    continue;
                }

                var updates = snapshotGroup.SelectMany(s => GetUpdatesForSnapshot(snapshotGroup.Key, s)).Where(u => u != null).ToArray();
                if (!updates.Any())
                {
                    continue;
                }

                analyzer._analysisComplete = false;
                Interlocked.Increment(ref analyzer._parsePending);

                tasks.Add(Tuple.Create(snapshotGroup.ToArray(), analyzer.SendRequestAsync(
                                           new AP.FileUpdateRequest {
                    documentUri = entry.DocumentUri,
                    updates     = updates
                }
                                           )));
            }

            var needRetry = new List <ITextSnapshot>();

            foreach (var task in tasks)
            {
                var res = await task.Item2;

                if (res?.failed ?? false)
                {
                    Interlocked.Decrement(ref analyzer._parsePending);
                    if (res != null)
                    {
                        needRetry.AddRange(task.Item1);
                    }
                }
                else
                {
                    analyzer.OnAnalysisStarted();
                    ValidateBufferContents(task.Item1, res);
                }
            }

            if (retryOnFailure && needRetry.Any())
            {
                foreach (var bi in needRetry.Select(s => PythonTextBufferInfo.TryGetForBuffer(s.TextBuffer)))
                {
                    bi.ClearSentSnapshot();
                }

                await ParseBuffersAsync(services, analyzer, needRetry, false);
            }
        }