/// <summary> /// Creates a new ProjectEntry for the collection of buffers. /// </summary> private void ReAnalyzeTextBuffers(BufferParser bufferParser) { ITextBuffer[] buffers = bufferParser.Buffers; var projEntry = CreateProjectEntry(buffers[0], new SnapshotCookie(buffers[0].CurrentSnapshot)); foreach (var buffer in buffers) { buffer.Properties.RemoveProperty(typeof(IProjectEntry)); buffer.Properties.AddProperty(typeof(IProjectEntry), projEntry); var classifier = buffer.GetPythonClassifier(); if (classifier != null) { ((PythonClassifier)classifier).NewVersion(); } } bufferParser._currentProjEntry = _openFiles[bufferParser] = projEntry; bufferParser._parser = this; foreach (var buffer in buffers) { DropDownBarClient client; if (buffer.Properties.TryGetProperty <DropDownBarClient>(typeof(DropDownBarClient), out client)) { client.UpdateProjectEntry(projEntry); } } bufferParser.Requeue(); }
public void StopMonitoringTextBuffer(BufferParser bufferParser) { bufferParser.StopMonitoring(); lock (_openFiles) { _openFiles.Remove(bufferParser); } }
internal void ClearBufferParser(BufferParser expected) { lock (_bufferParserLock) { Debug.Assert(_bufferParser != null && expected == _bufferParser); _bufferParser = null; } }
/// <summary> /// Parses the specified text buffer. Continues to monitor the parsed buffer and updates /// the parse tree asynchronously as the buffer changes. /// </summary> /// <param name="buffer"></param> public BufferParser EnqueueBuffer(IProjectEntry projEntry, ITextView textView, ITextBuffer buffer) { // only attach one parser to each buffer, we can get multiple enqueue's // for example if a document is already open when loading a project. BufferParser bufferParser; if (!buffer.Properties.TryGetProperty <BufferParser>(typeof(BufferParser), out bufferParser)) { Dispatcher dispatcher = null; var uiElement = textView as UIElement; if (uiElement != null) { dispatcher = uiElement.Dispatcher; } bufferParser = new BufferParser(this, dispatcher, projEntry, _parser, buffer); var curSnapshot = buffer.CurrentSnapshot; var severity = _parser.PyService.GeneralOptions.IndentationInconsistencySeverity; bufferParser.EnqueingEntry(); EnqueWorker(() => { _parser.ParseBuffers(bufferParser, severity, curSnapshot); }); } else { bufferParser.AttachedViews++; } return(bufferParser); }
public static async Task<BufferParser> CreateAsync(AnalysisEntry analysis, VsProjectAnalyzer parser, ITextBuffer buffer) { var res = new BufferParser(analysis, parser, buffer); using (new DebugTimer("BufferParser.ParseBuffers", 100)) { // lock not necessary for _bufferInfo, no one has access to us yet... await res.ParseBuffers(new[] { buffer.CurrentSnapshot }, new[] { res._bufferInfo[buffer] }); } return res; }
internal async Task <BufferParser> GetOrCreateBufferParser( VsProjectAnalyzer analyzer, ITextBuffer buffer, Action <BufferParser> onCreate, Action <BufferParser> onGet ) { BufferParser bp; TaskCompletionSource <BufferParser> bpt = null, cbpt = null, tcs = null; lock (_bufferParserLock) { bp = _bufferParser; if (bp == null) { cbpt = _createBufferParserTask; bpt = _bufferParserTask; if (cbpt == null) { _createBufferParserTask = tcs = new TaskCompletionSource <BufferParser>(); if (bpt == null) { _bufferParserTask = tcs; } } } } // There is an existing task doing creation, so wait on it. if (cbpt != null) { bp = await cbpt.Task; } if (bp != null) { onGet(bp); return(bp); } bp = await BufferParser.CreateAsync(this, analyzer, buffer); lock (_bufferParserLock) { _bufferParser = bp; _bufferParserTask = null; _createBufferParserTask = null; } onCreate(bp); tcs.TrySetResult(bp); bpt?.TrySetResult(bp); NotifyAllRegistrations(bp); return(bp); }
internal static async Task <BufferParser> CreateAsync(AnalysisEntry analysis, VsProjectAnalyzer parser, ITextBuffer buffer) { var res = new BufferParser(analysis, parser, buffer); using (new DebugTimer("BufferParser.ParseBuffers", 100)) { // lock not necessary for _bufferInfo, no one has access to us yet... await res.ParseBuffers(new[] { buffer.CurrentSnapshot }, new[] { res._bufferInfo[buffer] }); } return(res); }
internal void ClearBufferParser(BufferParser expected) { lock (_bufferParserLock) { Debug.Assert(_bufferParser != null && expected == _bufferParser); _bufferParser = null; _bufferParserTask?.TrySetCanceled(); _bufferParserTask = null; _createBufferParserTask?.TrySetCanceled(); _createBufferParserTask = null; } }
/// <summary> /// Attaches events for invoking Statement completion /// </summary> /// <param name="subjectBuffers"></param> /// <param name="textView"></param> /// <param name="completionBrokerMap"></param> public IntellisenseController(IntellisenseControllerProvider provider, IList <ITextBuffer> subjectBuffers, ITextView textView, BufferParser bufferParser) { _subjectBuffers = subjectBuffers; _textView = textView; _provider = provider; _editOps = provider._EditOperationsFactory.GetEditorOperations(textView); _incSearch = provider._IncrementalSearch.GetIncrementalSearch(textView); _textView.MouseHover += new EventHandler <MouseHoverEventArgs>(TextViewMouseHover); _bufferParser = bufferParser; textView.Properties.AddProperty(typeof(IntellisenseController), this); // added so our key processors can get back to us AttachKeyboardFilter(); }
internal void AddBuffer(ITextBuffer buffer) { BufferParser bp; lock (_bufferParserLock) { bp = _bufferParser; if (bp == null) { _bufferParser = bp = new BufferParser(this); } bp.AddBuffer(buffer); } }
private void NotifyAllRegistrations(BufferParser bufferParser) { foreach (var notify in bufferParser.Buffers.SelectMany(b => b.GetNewAnalysisEntryRegistrations())) { notify(this); } foreach (var notify in bufferParser.Buffers.SelectMany(b => b.GetParseTreeRegistrations())) { notify(this); } foreach (var notify in bufferParser.Buffers.SelectMany(b => b.GetNewAnalysisRegistrations())) { notify(this); } }
internal BufferParser GetOrCreateBufferParser(PythonEditorServices services) { BufferParser parser; if (!_bufferParser.TryGetTarget(out parser) || parser == null || parser.IsDisposed) { parser = new BufferParser(services, Analyzer, Path) { IsTemporaryFile = IsTemporaryFile, SuppressErrorList = SuppressErrorList }; _bufferParser.SetTarget(parser); } return(parser); }
/// <summary> /// Detaches the events /// </summary> /// <param name="textView"></param> public void Detach(ITextView textView) { if (_textView == null) { throw new InvalidOperationException("Already detached from text view"); } if (textView != _textView) { throw new ArgumentException("Not attached to specified text view", "textView"); } _textView.MouseHover -= TextViewMouseHover; _textView.Properties.RemoveProperty(typeof(IntellisenseController)); DetachKeyboardFilter(); _bufferParser = null; }
/// <summary> /// Parses the specified text buffer. Continues to monitor the parsed buffer and updates /// the parse tree asynchronously as the buffer changes. /// </summary> /// <param name="buffer"></param> public BufferParser EnqueueBuffer(IProjectEntry projEntry, ITextBuffer buffer) { // only attach one parser to each buffer, we can get multiple enqueue's // for example if a document is already open when loading a project. BufferParser bufferParser; if (!buffer.Properties.TryGetProperty <BufferParser>(typeof(BufferParser), out bufferParser)) { bufferParser = new BufferParser(projEntry, _parser, new[] { buffer }); buffer.Properties.AddProperty(typeof(BufferParser), bufferParser); var curSnapshot = buffer.CurrentSnapshot; var severity = PythonToolsPackage.Instance != null ? PythonToolsPackage.Instance.OptionsPage.IndentationInconsistencySeverity : Severity.Ignore; EnqueWorker(() => { _parser.ParseBuffers(bufferParser, severity, curSnapshot); }); } return(bufferParser); }
/// <summary> /// Parses the specified text buffer. Continues to monitor the parsed buffer and updates /// the parse tree asynchronously as the buffer changes. /// </summary> /// <param name="buffer"></param> public BufferParser EnqueueBuffer(IProjectEntry projEntry, ITextView textView, ITextBuffer buffer) { // only attach one parser to each buffer, we can get multiple enqueue's // for example if a document is already open when loading a project. BufferParser bufferParser; if (!buffer.Properties.TryGetProperty<BufferParser>(typeof(BufferParser), out bufferParser)) { Dispatcher dispatcher = null; var uiElement = textView as UIElement; if (uiElement != null) { dispatcher = uiElement.Dispatcher; } bufferParser = new BufferParser(this, dispatcher, projEntry, _parser, buffer); var curSnapshot = buffer.CurrentSnapshot; var severity = _parser.PyService.GeneralOptions.IndentationInconsistencySeverity; bufferParser.EnqueingEntry(); EnqueWorker(() => { _parser.ParseBuffers(bufferParser, severity, curSnapshot); }); } else { bufferParser.AttachedViews++; } return bufferParser; }
internal void SetBufferParser(BufferParser bufferParser) { Utilities.CheckNotNull(bufferParser, "Cannot set buffer parser multiple times"); _bufferParser = bufferParser; }
public MonitoredBufferResult(BufferParser bufferParser, AnalysisEntry projectEntry) { BufferParser = bufferParser; AnalysisEntry = projectEntry; }
public void ParseBuffers(BufferParser bufferParser, Severity indentationSeverity, params ITextSnapshot[] snapshots) { IProjectEntry analysis; lock (_openFiles) { if (!_openFiles.TryGetValue(bufferParser, out analysis)) { return; } } IPythonProjectEntry pyProjEntry = analysis as IPythonProjectEntry; List <PythonAst> asts = new List <PythonAst>(); bool hasErrors = false; foreach (var snapshot in snapshots) { var snapshotContent = new SnapshotSpanSourceCodeReader(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); if (pyProjEntry != null && snapshot.TextBuffer.ContentType.IsOfType(PythonCoreConstants.ContentType)) { if (!snapshot.IsReplBufferWithCommand()) { PythonAst ast; CollectingErrorSink errorSink; ParsePythonCode(snapshotContent, indentationSeverity, out ast, out errorSink); if (ast != null) { asts.Add(ast); if (errorSink.Errors.Count != 0) { hasErrors = true; } // update squiggles for the buffer var buffer = snapshot.TextBuffer; SimpleTagger <ErrorTag> squiggles = _errorProvider.GetErrorTagger(snapshot.TextBuffer); squiggles.RemoveTagSpans(x => true); TaskProvider provider = GetTaskListProviderForProject(bufferParser._currentProjEntry); AddWarnings(snapshot, errorSink, squiggles, provider); AddErrors(snapshot, errorSink, squiggles, provider); UpdateErrorList(errorSink, buffer.GetFilePath(), provider); } } } else { // other file such as XAML IExternalProjectEntry externalEntry; if ((externalEntry = (analysis as IExternalProjectEntry)) != null) { externalEntry.ParseContent(snapshotContent, new SnapshotCookie(snapshotContent.Snapshot)); _analysisQueue.Enqueue(analysis, AnalysisPriority.High); } } } if ((!hasErrors && asts.Count > 0) || asts.Count > 1) { // only update the AST when we're error free, this way we don't remove // a useful analysis with an incomplete and useless analysis. // If we have more than one AST we're in the REPL - we'll update the // AST in that case as errors won't go away. PythonAst finalAst; if (asts.Count == 1) { finalAst = asts[0]; } else { // multiple ASTs, merge them together List <Statement> bodies = new List <Statement>(); foreach (var ast in asts) { bodies.Add(ast.Body); } finalAst = new PythonAst(new SuiteStatement(bodies.ToArray()), new int[0]); } pyProjEntry.UpdateTree(finalAst, new SnapshotCookie(snapshots[0])); // SnapshotCookie is ot entirely right, we should merge the snapshots _analysisQueue.Enqueue(analysis, AnalysisPriority.High); } }
public MonitoredBufferResult(BufferParser bufferParser, IProjectEntry projectEntry) { BufferParser = bufferParser; ProjectEntry = projectEntry; }
public MonitoredBufferResult(BufferParser bufferParser, ITextView textView, IProjectEntry projectEntry) { BufferParser = bufferParser; TextView = textView; ProjectEntry = projectEntry; }
internal void StopMonitoringTextBuffer(BufferParser bufferParser, ITextView textView) { bufferParser.StopMonitoring(); lock (_openFiles) { _openFiles.Remove(bufferParser); } _unresolvedSquiggles.StopListening(bufferParser._currentProjEntry as IPythonProjectEntry); _errorProvider.ClearErrorSource(bufferParser._currentProjEntry, ParserTaskMoniker); _errorProvider.ClearErrorSource(bufferParser._currentProjEntry, UnresolvedImportMoniker); if (ImplicitProject) { // remove the file from the error list _errorProvider.Clear(bufferParser._currentProjEntry, ParserTaskMoniker); _errorProvider.Clear(bufferParser._currentProjEntry, UnresolvedImportMoniker); } _commentTaskProvider.ClearErrorSource(bufferParser._currentProjEntry, ParserTaskMoniker); if (ImplicitProject) { // remove the file from the error list _commentTaskProvider.Clear(bufferParser._currentProjEntry, ParserTaskMoniker); } }
/// <summary> /// Creates a new ProjectEntry for the collection of buffers. /// /// _openFiles must be locked when calling this function. /// </summary> internal void ReAnalyzeTextBuffers(BufferParser bufferParser) { ITextBuffer[] buffers = bufferParser.Buffers; if (buffers.Length > 0) { _errorProvider.ClearErrorSource(bufferParser._currentProjEntry, ParserTaskMoniker); _errorProvider.ClearErrorSource(bufferParser._currentProjEntry, UnresolvedImportMoniker); _commentTaskProvider.ClearErrorSource(bufferParser._currentProjEntry, ParserTaskMoniker); _unresolvedSquiggles.StopListening(bufferParser._currentProjEntry as IPythonProjectEntry); var projEntry = CreateProjectEntry(buffers[0], new SnapshotCookie(buffers[0].CurrentSnapshot)); bool doSquiggles = !buffers[0].Properties.ContainsProperty(typeof(IInteractiveEvaluator)); if (doSquiggles) { _unresolvedSquiggles.ListenForNextNewAnalysis(projEntry as IPythonProjectEntry); } foreach (var buffer in buffers) { buffer.Properties.RemoveProperty(typeof(IProjectEntry)); buffer.Properties.AddProperty(typeof(IProjectEntry), projEntry); var classifier = buffer.GetPythonClassifier(); if (classifier != null) { classifier.NewVersion(); } var classifier2 = buffer.GetPythonAnalysisClassifier(); if (classifier2 != null) { classifier2.NewVersion(); } ConnectErrorList(projEntry, buffer); if (doSquiggles) { _errorProvider.AddBufferForErrorSource(projEntry, UnresolvedImportMoniker, buffer); } } bufferParser._currentProjEntry = _openFiles[bufferParser] = projEntry; bufferParser._parser = this; foreach (var buffer in buffers) { // A buffer may have multiple DropDownBarClients, given one may open multiple CodeWindows // over a single buffer using Window/New Window List<DropDownBarClient> clients; if (buffer.Properties.TryGetProperty<List<DropDownBarClient>>(typeof(DropDownBarClient), out clients)) { foreach (var client in clients) { client.UpdateProjectEntry(projEntry); } } } bufferParser.Requeue(); } }
internal void ParseBuffers(BufferParser bufferParser, Severity indentationSeverity, params ITextSnapshot[] snapshots) { IProjectEntry entry = bufferParser._currentProjEntry; IPythonProjectEntry pyProjEntry = entry as IPythonProjectEntry; List<PythonAst> asts = new List<PythonAst>(); foreach (var snapshot in snapshots) { if (snapshot.TextBuffer.Properties.ContainsProperty(PythonReplEvaluator.InputBeforeReset)) { continue; } if (snapshot.IsReplBufferWithCommand()) { continue; } if (pyProjEntry != null && snapshot.TextBuffer.ContentType.IsOfType(PythonCoreConstants.ContentType)) { PythonAst ast; CollectingErrorSink errorSink; List<TaskProviderItem> commentTasks; var reader = new SnapshotSpanSourceCodeReader(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); ParsePythonCode(snapshot, reader, indentationSeverity, out ast, out errorSink, out commentTasks); if (ast != null) { asts.Add(ast); } // update squiggles for the buffer UpdateErrorsAndWarnings(entry, snapshot, errorSink, commentTasks); } else { // other file such as XAML IExternalProjectEntry externalEntry; if ((externalEntry = (entry as IExternalProjectEntry)) != null) { var snapshotContent = new SnapshotSpanSourceCodeReader(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); externalEntry.ParseContent(snapshotContent, new SnapshotCookie(snapshotContent.Snapshot)); _analysisQueue.Enqueue(entry, AnalysisPriority.High); } } } if (pyProjEntry != null) { if (asts.Count > 0) { PythonAst finalAst; if (asts.Count == 1) { finalAst = asts[0]; } else { // multiple ASTs, merge them together finalAst = new PythonAst( new SuiteStatement(asts.Select(ast => ast.Body).ToArray()), new int[0], asts[0].LanguageVersion ); } pyProjEntry.UpdateTree(finalAst, new SnapshotCookie(snapshots[0])); // SnapshotCookie is not entirely right, we should merge the snapshots _analysisQueue.Enqueue(entry, AnalysisPriority.High); } else { // indicate that we are done parsing. PythonAst prevTree; IAnalysisCookie prevCookie; pyProjEntry.GetTreeAndCookie(out prevTree, out prevCookie); pyProjEntry.UpdateTree(prevTree, prevCookie); } } }