/// <summary> /// This method can take some time to finish. It's not threaded /// </summary> /// <returns> /// A <see cref="ParsedDocument"/> that contains the current dom. /// </returns> public override async Task <ParsedDocument> UpdateParseDocument() { try { await EnsureAnalysisDocumentIsOpen(); string currentParseFile = GetCurrentParseFileName(); var editor = Editor; if (editor == null || string.IsNullOrEmpty(currentParseFile)) { return(null); } var currentParseText = editor.CreateDocumentSnapshot(); CancelOldParsing(); var project = Project; var options = new ParseOptions { Project = project, Content = currentParseText, FileName = currentParseFile, OldParsedDocument = parsedDocument, RoslynDocument = AnalysisDocument, IsAdhocProject = false }; if (project != null && typeSystemService.CanParseProjections(project, Editor.MimeType, FileName)) { var projectFile = project.GetProjectFile(currentParseFile); if (projectFile != null) { options.BuildAction = projectFile.BuildAction; } var p = await typeSystemService.ParseProjection(options, editor.MimeType); if (p != null) { this.parsedDocument = p.ParsedDocument; var projections = p.Projections; foreach (var p2 in projections) { p2.CreateProjectedEditor(this); } Editor.SetOrUpdateProjections(this, projections, p.DisabledProjectionFeatures); } } else { this.parsedDocument = await typeSystemService.ParseFile(options, editor.MimeType) ?? this.parsedDocument; } } finally { OnDocumentParsed(EventArgs.Empty); } return(this.parsedDocument); }
async void StartReparseThreadDelayed(FilePath currentParseFile) { var editor = Editor; if (editor == null || editor.IsDisposed) { return; } // Don't directly parse the document because doing it at every key press is // very inefficient. Do it after a small delay instead, so several changes can // be parsed at the same time. await EnsureAnalysisDocumentIsOpen(); var currentParseText = editor.CreateSnapshot(); string mimeType = editor.MimeType; CancelOldParsing(); var token = parseTokenSource.Token; var currentProject = adhocProject ?? Project; var projectsContainingFile = currentProject?.ParentSolution?.GetProjectsContainingFile(currentParseFile); if (projectsContainingFile == null || !projectsContainingFile.Any()) { projectsContainingFile = new Project [] { currentProject } } ; ThreadPool.QueueUserWorkItem(delegate { foreach (var project in projectsContainingFile) { var projectFile = project?.GetProjectFile(currentParseFile); TypeSystemService.AddSkippedFile(currentParseFile); var options = new ParseOptions { Project = project, Content = currentParseText, FileName = currentParseFile, OldParsedDocument = parsedDocument, RoslynDocument = AnalysisDocument, IsAdhocProject = IsAdHocProject }; if (projectFile != null) { options.BuildAction = projectFile.BuildAction; } if (project != null && TypeSystemService.CanParseProjections(project, mimeType, currentParseFile)) { TypeSystemService.ParseProjection(options, mimeType, token).ContinueWith((task, state) => { if (token.IsCancellationRequested) { return; } if (currentProject != state) { return; } Application.Invoke((o, args) => { // this may be called after the document has closed, in that case the OnDocumentParsed event shouldn't be invoked. var taskResult = task.Result; if (isClosed || taskResult == null || token.IsCancellationRequested) { return; } this.parsedDocument = taskResult.ParsedDocument; var projections = taskResult.Projections; foreach (var p2 in projections) { p2.CreateProjectedEditor(this); } Editor.SetOrUpdateProjections(this, projections, taskResult.DisabledProjectionFeatures); OnDocumentParsed(EventArgs.Empty); }); }, project, TaskContinuationOptions.OnlyOnRanToCompletion); } else if (project == null || currentProject == project) { TypeSystemService.ParseFile(options, mimeType, token).ContinueWith(task => { if (token.IsCancellationRequested) { return; } Application.Invoke((o, args) => { // this may be called after the document has closed, in that case the OnDocumentParsed event shouldn't be invoked. if (isClosed || task.Result == null || token.IsCancellationRequested) { return; } this.parsedDocument = task.Result; OnDocumentParsed(EventArgs.Empty); }); }, TaskContinuationOptions.OnlyOnRanToCompletion); } } }); }