Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs531
1 files changed, 277 insertions, 254 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs
index eff3218cc9..c96d9fb360 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs
@@ -47,23 +47,25 @@ using MonoDevelop.Ide.Extensions;
using System.Linq;
using System.Threading;
using MonoDevelop.Ide.TypeSystem;
-using ICSharpCode.NRefactory;
-using ICSharpCode.NRefactory.TypeSystem;
-using ICSharpCode.NRefactory.TypeSystem.Implementation;
using System.Text;
using System.Collections.ObjectModel;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.Options;
+using MonoDevelop.Ide.Editor;
+using MonoDevelop.Ide.Editor.Highlighting;
+using MonoDevelop.Core.Text;
namespace MonoDevelop.Ide.Gui
{
- public class Document : ICSharpCode.NRefactory.AbstractAnnotatable
+
+ public class Document : DocumentContext
{
internal object MemoryProbe = Counters.DocumentsInMemory.CreateMemoryProbe ();
IWorkbenchWindow window;
- TextEditorExtension editorExtension;
ParsedDocument parsedDocument;
- IProjectContent singleFileContext;
- Mono.TextEditor.ITextEditorDataProvider provider = null;
+ FilePath analysisDocumentFileName;
+ Microsoft.CodeAnalysis.DocumentId analysisDocument;
const int ParseDelay = 600;
@@ -75,12 +77,20 @@ namespace MonoDevelop.Ide.Gui
get;
set;
}
-
- public TextEditorExtension EditorExtension {
- get { return this.editorExtension; }
+
+ /// <summary>
+ /// Returns the roslyn document for this document. This may return <c>null</c> if it's no compileable document.
+ /// Even if it's a C# file.
+ /// </summary>
+ public override Microsoft.CodeAnalysis.Document AnalysisDocument {
+ get {
+ if (analysisDocument == null)
+ return null;
+ return TypeSystemService.GetCodeAnalysisDocument (analysisDocument);
+ }
}
- public T GetContent<T> () where T : class
+ public override T GetContent<T> ()
{
if (window == null)
return null;
@@ -97,39 +107,30 @@ namespace MonoDevelop.Ide.Gui
return ret;
}
- //no, so look through the TexteditorExtensions as well
- TextEditorExtension nextExtension = editorExtension;
- while (nextExtension != null) {
- if (typeof(T).IsAssignableFrom (nextExtension.GetType ()))
- return nextExtension as T;
- nextExtension = nextExtension.Next as TextEditorExtension;
+ //If we didn't find in ActiveView or ViewContent... Try in SubViews
+ foreach (var subView in window.SubViewContents) {
+ foreach (var cnt in subView.GetContents<T> ()) {
+ return cnt;
+ }
}
+
return null;
}
- public IEnumerable<T> GetContents<T> () where T : class
+ public override IEnumerable<T> GetContents<T> ()
{
- //check whether the ViewContent can return the type directly
- T ret = (T) Window.ActiveViewContent.GetContent (typeof(T));
- if (ret != null)
- yield return ret;
-
- //check the primary viewcontent
- //not sure if this is the right thing to do, but things depend on this behaviour
- if (Window.ViewContent != Window.ActiveViewContent) {
- ret = (T) Window.ViewContent.GetContent (typeof(T));
- if (ret != null)
- yield return ret;
+ foreach (var cnt in window.ViewContent.GetContents<T> ()) {
+ yield return cnt;
}
-
- //no, so look through the TexteditorExtensions as well
- TextEditorExtension nextExtension = editorExtension;
- while (nextExtension != null) {
- if (typeof(T).IsAssignableFrom (nextExtension.GetType ()))
- yield return nextExtension as T;
- nextExtension = nextExtension.Next as TextEditorExtension;
+
+ foreach (var subView in window.SubViewContents) {
+ foreach (var cnt in subView.GetContents<T> ()) {
+ yield return cnt;
+ }
}
}
+
+
static Document ()
{
if (IdeApp.Workbench != null) {
@@ -155,6 +156,19 @@ namespace MonoDevelop.Ide.Gui
if (window.ViewContent.Project != null)
window.ViewContent.Project.Modified += HandleProjectModified;
window.ViewsChanged += HandleViewsChanged;
+ window.ViewContent.ContentNameChanged += delegate {
+ analysisDocument = null;
+ };
+ MonoDevelopWorkspace.LoadingFinished += TypeSystemService_WorkspaceItemLoaded;
+ }
+
+ void TypeSystemService_WorkspaceItemLoaded (object sender, EventArgs e)
+ {
+ if (adhocProject == null)
+ analysisDocument = null;
+ EnsureAnalysisDocumentIsOpen ();
+ if (analysisDocument != null)
+ StartReparseThread ();
}
/* void UpdateRegisteredDom (object sender, ProjectDomEventArgs e)
@@ -182,13 +196,12 @@ namespace MonoDevelop.Ide.Gui
get { return !Window.ViewContent.IsViewOnly && (Window.ViewContent.ContentName == null || Window.ViewContent.IsDirty); }
set { Window.ViewContent.IsDirty = value; }
}
-
- public bool HasProject {
- get { return Window != null ? Window.ViewContent.Project != null : false; }
- }
-
- public Project Project {
- get { return Window != null ? Window.ViewContent.Project : null; }
+
+ FilePath adHocFile;
+ Project adhocProject;
+
+ public override Project Project {
+ get { return (Window != null ? Window.ViewContent.Project : null); }
/* set {
Window.ViewContent.Project = value;
if (value != null)
@@ -199,7 +212,7 @@ namespace MonoDevelop.Ide.Gui
}*/
}
- public bool IsCompileableInProject {
+ public override bool IsCompileableInProject {
get {
var project = Project;
if (project == null)
@@ -220,19 +233,15 @@ namespace MonoDevelop.Ide.Gui
}
}
- public IProjectContent ProjectContent {
- get {
- return Project != null ? TypeSystemService.GetProjectContext (Project) : GetProjectContext ();
- }
- }
-
- public virtual ICompilation Compilation {
- get {
- return Project != null ? TypeSystemService.GetCompilation (Project) : GetProjectContext ().CreateCompilation ();
- }
+ public Task<Microsoft.CodeAnalysis.Compilation> GetCompilationAsync(CancellationToken cancellationToken = default(CancellationToken))
+ {
+ var project = TypeSystemService.GetCodeAnalysisProject (Project ?? adhocProject);
+ if (project == null)
+ return new Task<Microsoft.CodeAnalysis.Compilation> (() => null);
+ return project.GetCompilationAsync (cancellationToken);
}
-
- public virtual ParsedDocument ParsedDocument {
+
+ public override ParsedDocument ParsedDocument {
get {
return parsedDocument;
}
@@ -300,21 +309,16 @@ namespace MonoDevelop.Ide.Gui
return new DocumentView (this, content);
}
- public string Name {
+ public override string Name {
get {
IViewContent view = Window.ViewContent;
return view.IsUntitled ? view.UntitledName : view.ContentName;
}
}
- public Mono.TextEditor.TextEditorData Editor {
+ public TextEditor Editor {
get {
- if (provider == null) {
- provider = GetContent <Mono.TextEditor.ITextEditorDataProvider> ();
- if (provider == null)
- return null;
- }
- return provider.GetTextEditorData ();
+ return GetContent <TextEditor> ();
}
}
@@ -378,21 +382,21 @@ namespace MonoDevelop.Ide.Gui
// Set the file time of the current document after the file time of the written file, to prevent double file updates.
// Note that the parsed document may be overwritten by a background thread to a more recent one.
var doc = parsedDocument;
- if (doc != null && doc.ParsedFile != null) {
+ if (doc != null) {
string fileName = Window.ViewContent.ContentName;
try {
// filename could be null if the user cancelled SaveAs and this is a new & unsaved file
if (fileName != null)
- doc.ParsedFile.LastWriteTime = File.GetLastWriteTimeUtc (fileName);
+ doc.LastWriteTimeUtc = File.GetLastWriteTimeUtc (fileName);
} catch (Exception e) {
- doc.ParsedFile.LastWriteTime = DateTime.UtcNow;
+ doc.LastWriteTimeUtc = DateTime.UtcNow;
LoggingService.LogWarning ("Exception while getting the write time from " + fileName, e);
}
}
TypeSystemService.TrackFileChanges = true;
}
}
-
+
public void SaveAs ()
{
SaveAs (null);
@@ -406,11 +410,11 @@ namespace MonoDevelop.Ide.Gui
Encoding encoding = null;
- IEncodedTextContent tbuffer = GetContent <IEncodedTextContent> ();
+ var tbuffer = GetContent <ITextSource> ();
if (tbuffer != null) {
- encoding = tbuffer.SourceEncoding;
+ encoding = tbuffer.Encoding;
if (encoding == null)
- encoding = Encoding.Default;
+ encoding = Encoding.UTF8;
}
if (filename == null) {
@@ -446,16 +450,13 @@ namespace MonoDevelop.Ide.Gui
// save backup first
if ((bool)PropertyService.Get ("SharpDevelop.CreateBackupCopy", false)) {
if (tbuffer != null && encoding != null)
- tbuffer.Save (filename + "~", encoding);
+ TextFileUtility.WriteText (filename + "~", tbuffer.Text, encoding, tbuffer.UseBOM);
else
- Window.ViewContent.Save (filename + "~");
+ Window.ViewContent.Save (new FileSaveInformation (filename + "~", encoding));
}
TypeSystemService.RemoveSkippedfile (FileName);
// do actual save
- if (tbuffer != null && encoding != null)
- tbuffer.Save (filename, encoding);
- else
- Window.ViewContent.Save (filename);
+ Window.ViewContent.Save (new FileSaveInformation (filename + "~", encoding));
FileService.NotifyFileChanged (filename);
DesktopService.RecentFiles.AddFile (filename, (Project)null);
@@ -468,12 +469,11 @@ namespace MonoDevelop.Ide.Gui
{
return ((SdiWorkspaceWindow)Window).CloseWindow (false, true);
}
-
- void OnSaved (EventArgs args)
+
+ protected override void OnSaved (EventArgs e)
{
IdeApp.Workbench.SaveFileStatus ();
- if (Saved != null)
- Saved (this, args);
+ base.OnSaved (e);
}
public void CancelParseTimeout ()
@@ -518,8 +518,14 @@ namespace MonoDevelop.Ide.Gui
internal void DisposeDocument ()
{
- DetachExtensionChain ();
- RemoveAnnotations (typeof(System.Object));
+ if (analysisDocument != null) {
+ TypeSystemService.InformDocumentClose (analysisDocument, FileName);
+ analysisDocument = null;
+ }
+ UnloadAdhocProject ();
+ if (Editor != null) {
+ Editor.Dispose ();
+ }
if (window is SdiWorkspaceWindow)
((SdiWorkspaceWindow)window).DetachFromPathedDocument ();
window.Closed -= OnClosed;
@@ -531,11 +537,12 @@ namespace MonoDevelop.Ide.Gui
if (window.ViewContent.Project != null)
window.ViewContent.Project.Modified -= HandleProjectModified;
window.ViewsChanged += HandleViewsChanged;
+ TypeSystemService.Workspace.WorkspaceChanged -= HandleWorkspaceChanged;
+ MonoDevelopWorkspace.LoadingFinished -= TypeSystemService_WorkspaceItemLoaded;
+
window = null;
parsedDocument = null;
- singleFileContext = null;
- provider = null;
views = null;
viewsRO = null;
}
@@ -587,84 +594,44 @@ namespace MonoDevelop.Ide.Gui
void InitializeExtensionChain ()
{
- DetachExtensionChain ();
- var editor = GetContent<IExtensibleTextEditor> ();
-
- ExtensionNodeList extensions = window.ExtensionContext.GetExtensionNodes ("/MonoDevelop/Ide/TextEditorExtensions", typeof(TextEditorExtensionNode));
- editorExtension = null;
- TextEditorExtension last = null;
- var mimetypeChain = DesktopService.GetMimeTypeInheritanceChainForFile (FileName).ToArray ();
- foreach (TextEditorExtensionNode extNode in extensions) {
- if (!extNode.Supports (FileName, mimetypeChain))
- continue;
- TextEditorExtension ext;
- try {
- ext = (TextEditorExtension)extNode.CreateInstance ();
- } catch (Exception e) {
- LoggingService.LogError ("Error while creating text editor extension :" + extNode.Id + "(" + extNode.Type +")", e);
- continue;
- }
- if (ext.ExtendsEditor (this, editor)) {
- if (last != null) {
- ext.Next = last.Next;
- last.Next = ext;
- last = ext;
- } else {
- editorExtension = last = ext;
- last.Next = editor.AttachExtension (editorExtension);
- }
- ext.Initialize (this);
- }
- }
+ Editor.InitializeExtensionChain (this);
+
if (window is SdiWorkspaceWindow)
((SdiWorkspaceWindow)window).AttachToPathedDocument (GetContent<MonoDevelop.Ide.Gui.Content.IPathedDocument> ());
- }
- void DetachExtensionChain ()
- {
- while (editorExtension != null) {
- try {
- editorExtension.Dispose ();
- } catch (Exception ex) {
- LoggingService.LogError ("Exception while disposing extension:" + editorExtension, ex);
- }
- editorExtension = editorExtension.Next as TextEditorExtension;
- }
- editorExtension = null;
}
- void InitializeEditor (IExtensibleTextEditor editor)
+ void InitializeEditor ()
{
- Editor.Document.TextReplaced += (o, a) => {
+ Editor.TextChanged += (o, a) => {
if (parsedDocument != null)
parsedDocument.IsInvalid = true;
- if (Editor.Document.IsInAtomicUndo) {
+ if (Editor.IsInAtomicUndo) {
wasEdited = true;
} else {
StartReparseThread ();
}
};
- Editor.Document.BeginUndo += delegate {
+ Editor.BeginAtomicUndoOperation += delegate {
wasEdited = false;
};
- Editor.Document.EndUndo += delegate {
+ Editor.EndAtomicUndoOperation += delegate {
if (wasEdited)
StartReparseThread ();
};
- Editor.Document.Undone += (o, a) => StartReparseThread ();
- Editor.Document.Redone += (o, a) => StartReparseThread ();
+// Editor.Undone += (o, a) => StartReparseThread ();
+// Editor.Redone += (o, a) => StartReparseThread ();
InitializeExtensionChain ();
}
internal void OnDocumentAttached ()
{
- IExtensibleTextEditor editor = GetContent<IExtensibleTextEditor> ();
- if (editor != null) {
- InitializeEditor (editor);
+ if (Editor != null) {
+ InitializeEditor ();
RunWhenLoaded (delegate { ListenToProjectLoad (Project); });
}
@@ -680,24 +647,25 @@ namespace MonoDevelop.Ide.Gui
public void RunWhenLoaded (System.Action action)
{
var e = Editor;
- if (e == null || e.Document == null) {
+ if (e == null) {
action ();
return;
}
- e.Document.RunWhenLoaded (action);
+ e.RunWhenLoaded (action);
}
- public void AttachToProject (Project project)
+ public override void AttachToProject (Project project)
{
SetProject (project);
}
- TypeSystemService.ProjectContentWrapper currentWrapper;
internal void SetProject (Project project)
{
if (Window == null || Window.ViewContent == null || Window.ViewContent.Project == project)
return;
- DetachExtensionChain ();
+ UnloadAdhocProject ();
+ if (adhocProject == null)
+ analysisDocument = null;
ISupportsProjectReload pr = GetContent<ISupportsProjectReload> ();
if (pr != null) {
// Unsubscribe project events
@@ -709,22 +677,19 @@ namespace MonoDevelop.Ide.Gui
if (project != null)
project.Modified += HandleProjectModified;
InitializeExtensionChain ();
-
+ TypeSystemService.Workspace.WorkspaceChanged += HandleWorkspaceChanged;
ListenToProjectLoad (project);
}
- void ListenToProjectLoad (Project project)
+ void HandleWorkspaceChanged (object sender, Microsoft.CodeAnalysis.WorkspaceChangeEventArgs e)
{
- if (currentWrapper != null) {
- currentWrapper.Loaded -= HandleInLoadChanged;
- currentWrapper = null;
- }
- if (project != null) {
- var wrapper = TypeSystemService.GetProjectContentWrapper (project);
- wrapper.Loaded += HandleInLoadChanged;
- currentWrapper = wrapper;
- currentWrapper.RequestLoad ();
+ if (e.Kind == Microsoft.CodeAnalysis.WorkspaceChangeKind.DocumentChanged && e.DocumentId == analysisDocument) {
+ OnDocumentParsed (EventArgs.Empty);
}
+ }
+
+ void ListenToProjectLoad (Project project)
+ {
StartReparseThread ();
}
@@ -746,18 +711,30 @@ namespace MonoDevelop.Ide.Gui
/// <returns>
/// A <see cref="ParsedDocument"/> that contains the current dom.
/// </returns>
- public ParsedDocument UpdateParseDocument ()
+ public override ParsedDocument UpdateParseDocument ()
{
try {
+ EnsureAnalysisDocumentIsOpen ();
string currentParseFile = FileName;
var editor = Editor;
if (editor == null || string.IsNullOrEmpty (currentParseFile))
return null;
TypeSystemService.AddSkippedFile (currentParseFile);
- string currentParseText = editor.Text;
- this.parsedDocument = TypeSystemService.ParseFile (Project, currentParseFile, editor.Document.MimeType, currentParseText);
- if (Project == null && this.parsedDocument != null) {
- singleFileContext = GetProjectContext ().AddOrUpdateFiles (parsedDocument.ParsedFile);
+ var currentParseText = editor.CreateDocumentSnapshot ();
+ CancelOldParsing();
+ var project = Project ?? adhocProject;
+ if (project != null && TypeSystemService.CanParseProjections (project, Editor.MimeType, FileName)) {
+ var task = TypeSystemService.ParseProjection (project, currentParseFile, editor.MimeType, currentParseText);
+ if (task.Result != null) {
+ var p = task.Result;
+ 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 = TypeSystemService.ParseFile (project, currentParseFile, editor.MimeType, currentParseText).Result ?? this.parsedDocument;
}
} finally {
@@ -765,89 +742,136 @@ namespace MonoDevelop.Ide.Gui
}
return this.parsedDocument;
}
+
+ uint parseTimeout = 0;
- static readonly Lazy<IUnresolvedAssembly> mscorlib = new Lazy<IUnresolvedAssembly> ( () => new IkvmLoader ().LoadAssemblyFile (typeof (object).Assembly.Location));
- static readonly Lazy<IUnresolvedAssembly> systemCore = new Lazy<IUnresolvedAssembly>( () => new IkvmLoader ().LoadAssemblyFile (typeof (System.Linq.Enumerable).Assembly.Location));
- static readonly Lazy<IUnresolvedAssembly> system = new Lazy<IUnresolvedAssembly>( () => new IkvmLoader ().LoadAssemblyFile (typeof (System.Uri).Assembly.Location));
-
- static IUnresolvedAssembly Mscorlib { get { return mscorlib.Value; } }
- static IUnresolvedAssembly SystemCore { get { return systemCore.Value; } }
- static IUnresolvedAssembly System { get { return system.Value; } }
-
- public bool IsProjectContextInUpdate {
- get {
- if (currentWrapper == null)
- return false;
- return !currentWrapper.IsLoaded;
+ void EnsureAnalysisDocumentIsOpen ()
+ {
+ if (analysisDocument != null)
+ return;
+ if (Editor == null) {
+ analysisDocument = null;
+ return;
+ }
+ analysisDocumentFileName = FileName;
+ if (Project != null) {
+ RoslynWorkspace = TypeSystemService.GetWorkspace (this.Project.ParentSolution);
+ analysisDocument = TypeSystemService.GetDocumentId (this.Project, this.FileName);
+ if (analysisDocument != null) {
+ TypeSystemService.InformDocumentOpen (analysisDocument, Editor);
+ }
+ } else {
+ lock (adhocProjectLock) {
+ if (adhocProject != null) {
+ return;
+ }
+ if (Editor != null && Editor.MimeType == "text/x-csharp") {
+ var newProject = new DotNetAssemblyProject (Microsoft.CodeAnalysis.LanguageNames.CSharp);
+ this.adhocProject = newProject;
+
+ newProject.Name = "InvisibleProject";
+ newProject.References.Add (new ProjectReference (ReferenceType.Package, "mscorlib"));
+ newProject.References.Add (new ProjectReference (ReferenceType.Package, "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"));
+ newProject.References.Add (new ProjectReference (ReferenceType.Package, "System.Core"));
+
+ newProject.FileName = "test.csproj";
+ adHocFile = Platform.IsWindows ? "C:\\a.cs" : "/a.cs";
+ newProject.Files.Add (new ProjectFile (adHocFile, BuildAction.Compile));
+
+ var solution = new Solution ();
+ solution.AddConfiguration ("", true);
+ solution.DefaultSolutionFolder.AddItem (newProject);
+ using (var monitor = new MonoDevelop.Core.ProgressMonitoring.NullProgressMonitor ())
+ RoslynWorkspace = TypeSystemService.Load (solution, monitor, false);
+ analysisDocument = TypeSystemService.GetDocumentId (RoslynWorkspace, adhocProject, adHocFile);
+ TypeSystemService.InformDocumentOpen (RoslynWorkspace, analysisDocument, Editor);
+ }
+ }
}
}
+ object adhocProjectLock = new object();
- public virtual IProjectContent GetProjectContext ()
+ void UnloadAdhocProject ()
{
- if (Project == null) {
- if (singleFileContext == null) {
- singleFileContext = new ICSharpCode.NRefactory.CSharp.CSharpProjectContent ();
- singleFileContext = singleFileContext.AddAssemblyReferences (new [] { Mscorlib, System, SystemCore });
- }
- if (parsedDocument != null)
- return singleFileContext.AddOrUpdateFiles (parsedDocument.ParsedFile);
- return singleFileContext;
+ lock (adhocProjectLock) {
+ if (adhocProject == null)
+ return;
+ TypeSystemService.Unload (adhocProject.ParentSolution.ParentWorkspace);
+ adhocProject = null;
}
-
- return TypeSystemService.GetProjectContext (Project);
}
-
- uint parseTimeout = 0;
+
object reparseLock = new object();
- internal void StartReparseThread ()
+ CancellationTokenSource parseTokenSource = new CancellationTokenSource();
+ int reparseQueue;
+ void CancelOldParsing()
{
- lock (reparseLock) {
- if (currentWrapper != null)
- currentWrapper.EnsureReferencesAreLoaded ();
+ parseTokenSource.Cancel ();
+ parseTokenSource = new CancellationTokenSource ();
+ }
+ internal void StartReparseThread ()
+ {
+ string currentParseFile = adhocProject != null ? adHocFile : FileName;
+ if (string.IsNullOrEmpty (currentParseFile))
+ return;
+ Interlocked.Increment (ref reparseQueue);
+ Application.Invoke (delegate {
+ if (Interlocked.Decrement (ref reparseQueue) != 0) {
+ 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.
- string currentParseFile = FileName;
- if (string.IsNullOrEmpty (currentParseFile))
- return;
+ EnsureAnalysisDocumentIsOpen ();
CancelParseTimeout ();
- if (IsProjectContextInUpdate) {
- return;
- }
- parseTimeout = GLib.Timeout.Add (ParseDelay, delegate {
- var editor = Editor;
- if (editor == null || IsProjectContextInUpdate) {
- parseTimeout = 0;
- return false;
- }
- string currentParseText = editor.Text;
- string mimeType = editor.Document.MimeType;
- ThreadPool.QueueUserWorkItem (delegate {
- if (IsProjectContextInUpdate) {
- return;
- }
- TypeSystemService.AddSkippedFile (currentParseFile);
- var currentParsedDocument = TypeSystemService.ParseFile (Project, currentParseFile, mimeType, currentParseText);
- Application.Invoke (delegate {
- // this may be called after the document has closed, in that case the OnDocumentParsed event shouldn't be invoked.
- if (isClosed)
+ var currentParseText = Editor.CreateSnapshot ();
+ string mimeType = Editor.MimeType;
+ CancelOldParsing ();
+ var token = parseTokenSource.Token;
+ var project = Project ?? adhocProject;
+ ThreadPool.QueueUserWorkItem (delegate {
+ TypeSystemService.AddSkippedFile (currentParseFile);
+ if (project != null && TypeSystemService.CanParseProjections (project, mimeType, currentParseFile)) {
+ TypeSystemService.ParseProjection (project, currentParseFile, mimeType, currentParseText, token).ContinueWith (task => {
+ if (token.IsCancellationRequested)
return;
- this.parsedDocument = currentParsedDocument;
- OnDocumentParsed (EventArgs.Empty);
- });
- });
+ Application.Invoke (delegate {
+ // 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);
+ });
+ }, TaskContinuationOptions.OnlyOnRanToCompletion);
+ } else {
+ TypeSystemService.ParseFile (project, currentParseFile, mimeType, currentParseText, token).ContinueWith (task => {
+ if (token.IsCancellationRequested)
+ return;
+ Application.Invoke (delegate {
+ // 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);
+ }
parseTimeout = 0;
- return false;
});
- }
+ });
}
/// <summary>
/// This method kicks off an async document parser and should be used instead of
/// <see cref="UpdateParseDocument"/> unless you need the parsed document immediately.
/// </summary>
- public void ReparseDocument ()
+ public override void ReparseDocument ()
{
StartReparseThread ();
}
@@ -855,8 +879,8 @@ namespace MonoDevelop.Ide.Gui
internal object ExtendedCommandTargetChain {
get {
// Only go through the text editor chain, if the text editor is selected as subview
- if (Window != null && Window.ActiveViewContent.GetContent (typeof(IExtensibleTextEditor)) != null)
- return editorExtension;
+ if (Window != null && Window.ActiveViewContent.GetContent (typeof(TextEditor)) != null)
+ return Editor.CommandRouter;
return null;
}
}
@@ -867,19 +891,10 @@ namespace MonoDevelop.Ide.Gui
window.ViewContent.Project = null;
}
- protected virtual void OnDocumentParsed (EventArgs e)
- {
- EventHandler handler = this.DocumentParsed;
- if (handler != null)
- handler (this, e);
- }
-
public event EventHandler Closed;
- public event EventHandler Saved;
public event EventHandler ViewChanged;
- public event EventHandler DocumentParsed;
-
+
public string[] CommentTags {
get {
if (IsFile)
@@ -893,30 +908,16 @@ namespace MonoDevelop.Ide.Gui
{
//Document doc = IdeApp.Workbench.ActiveDocument;
string loadedMimeType = DesktopService.GetMimeTypeForUri (fileName);
-
- Mono.TextEditor.Highlighting.SyntaxMode mode = null;
- foreach (string mt in DesktopService.GetMimeTypeInheritanceChain (loadedMimeType)) {
- mode = Mono.TextEditor.Highlighting.SyntaxModeService.GetSyntaxMode (null, mt);
- if (mode != null)
- break;
- }
-
- if (mode == null)
- return null;
-
- List<string> ctags;
- if (mode.Properties.TryGetValue ("LineComment", out ctags) && ctags.Count > 0) {
- return new string [] { ctags [0] };
- }
- List<string> tags = new List<string> ();
- if (mode.Properties.TryGetValue ("BlockCommentStart", out ctags))
- tags.Add (ctags [0]);
- if (mode.Properties.TryGetValue ("BlockCommentEnd", out ctags))
- tags.Add (ctags [0]);
- if (tags.Count == 2)
- return tags.ToArray ();
- else
- return null;
+
+ var result = TextEditorFactory.GetSyntaxProperties (loadedMimeType, "LineComment");
+ if (result != null)
+ return result;
+
+ var start = TextEditorFactory.GetSyntaxProperties (loadedMimeType, "BlockCommentStart");
+ var end = TextEditorFactory.GetSyntaxProperties (loadedMimeType, "BlockCommentEnd");
+ if (start != null && end != null)
+ return new [] { start[0], end[0] };
+ return null;
}
// public MonoDevelop.Projects.CodeGeneration.CodeGenerator CreateCodeGenerator ()
@@ -932,7 +933,29 @@ namespace MonoDevelop.Ide.Gui
public void DisableAutoScroll ()
{
if (IsFile)
- Mono.TextEditor.Utils.FileSettingsStore.Remove (FileName);
+ FileSettingsStore.Remove (FileName);
+ }
+
+ public override OptionSet GetOptionSet ()
+ {
+ return TypeSystemService.Workspace.Options;
+ }
+
+ internal override Task<IReadOnlyList<Editor.Projection.Projection>> GetPartialProjectionsAsync (CancellationToken cancellationToken = default(CancellationToken))
+ {
+ var parser = TypeSystemService.GetParser (Editor.MimeType);
+ if (parser == null)
+ return null;
+ var projectFile = Project.GetProjectFile (Editor.FileName);
+ if (projectFile == null)
+ return null;
+ if (!parser.CanGenerateProjection (Editor.MimeType, projectFile.BuildAction, Project.SupportedLanguages))
+ return null;
+ try {
+ return parser.GetPartialProjectionsAsync (this, Editor, parsedDocument, cancellationToken);
+ } catch (NotSupportedException) {
+ return null;
+ }
}
}