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:
authorMike Krüger <mkrueger@xamarin.com>2017-08-08 16:00:39 +0300
committerMike Krüger <mkrueger@xamarin.com>2017-08-08 16:00:39 +0300
commitd4d90f0f327092511d885ea80c66be92be92f950 (patch)
treecfeeff941d6c4645e59f0e4cde0b572bc1cbc32f /main/src/core/MonoDevelop.Ide
parent0748166561d4eca6d80ab5d7d24f5566c6ab5aea (diff)
[TextEditor] Implemented code lens subsystem & show references lenses.master-codelens
It's the rosyln code lens service driving the first code lens.
Diffstat (limited to 'main/src/core/MonoDevelop.Ide')
-rw-r--r--main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml5
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CodeLensTextEditorExtension.cs204
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/ITextLineMarker.cs8
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/InternalExtensionAPI/ITextMarkerFactory.cs1
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj1
5 files changed, 219 insertions, 0 deletions
diff --git a/main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml b/main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml
index b716716444..617f97a492 100644
--- a/main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml
+++ b/main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml
@@ -238,6 +238,10 @@
<ExtensionNode name = "Assembly" type = "MonoDevelop.Core.AddIns.AssemblyExtensionNode" />
</ExtensionPoint>
+ <ExtensionPoint path = "/MonoDevelop/Ide/CodeLensProvider" name = "Code lens provider">
+ <Description>Algorithm for providing code lenses in a file.</Description>
+ <ExtensionNode name="CodeLens" type="MonoDevelop.Ide.Extensions.MimeTypeExtensionNode"/>
+ </ExtensionPoint>
<!-- Extensions -->
<Extension path = "/MonoDevelop/Core/Applications">
@@ -320,6 +324,7 @@
<Class class = "MonoDevelop.Ide.Editor.TextMate.TextMateFoldingTextEditorExtension" />
<Class class = "MonoDevelop.Ide.Editor.TextMate.TextMateIndentationTextEditorExtension" />
<Class class = "MonoDevelop.Ide.Editor.TextMate.TextMateCompletionTextEditorExtension" />
+ <Class class = "MonoDevelop.Ide.Editor.Extension.CodeLensTextEditorExtension" />
<Class id="FinalStep" class = "MonoDevelop.Ide.Editor.Extension.TextEditorExtensionMarker" />
</Extension>
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CodeLensTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CodeLensTextEditorExtension.cs
new file mode 100644
index 0000000000..113071f296
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CodeLensTextEditorExtension.cs
@@ -0,0 +1,204 @@
+//
+// AbstractCodeLensExtension.cs
+//
+// Author:
+// Mike Krüger <mikkrg@microsoft.com>
+//
+// Copyright (c) 2017 Microsoft Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using MonoDevelop.Ide.Gui.Content;
+using System.Collections.Generic;
+using System.Linq;
+using MonoDevelop.Ide.FindInFiles;
+using System.Threading;
+using System.Threading.Tasks;
+using MonoDevelop.Core;
+using System.Diagnostics.CodeAnalysis;
+using MonoDevelop.Ide.Editor;
+using MonoDevelop.Core.Text;
+using System.Collections.Immutable;
+using Mono.Addins;
+using MonoDevelop.Ide.Extensions;
+using MonoDevelop.Ide.TypeSystem;
+using Cairo;
+
+namespace MonoDevelop.Ide.Editor.Extension
+{
+ public sealed class GtkCodeLansDrawingParameters : CodeLansDrawingParameters
+ {
+ public Pango.Layout Layout { get; private set; }
+ public Context Context { get; private set; }
+
+ public GtkCodeLansDrawingParameters (TextEditor editor, int lineNr, Xwt.Rectangle lineArea, double x, double y, Pango.Layout layout, Context context) : base (editor, lineNr, lineArea, x, y)
+ {
+ Layout = layout;
+ Context = context;
+ }
+ }
+
+ public abstract class CodeLansDrawingParameters
+ {
+ public TextEditor Editor { get; private set; }
+ public int LineNr { get; private set; }
+ public Xwt.Rectangle LineArea { get; private set; }
+
+ public double X { get; private set; }
+ public double Y { get; private set; }
+
+ public CodeLansDrawingParameters (TextEditor editor, int lineNr, Xwt.Rectangle lineArea, double x, double y)
+ {
+ Editor = editor;
+ LineNr = lineNr;
+ LineArea = lineArea;
+ X = x;
+ Y = y;
+ }
+ }
+
+ public abstract class CodeLens
+ {
+ public abstract TextSegment CodeLensSpan { get; }
+
+ public abstract void Draw (CodeLansDrawingParameters drawingParameters);
+
+ public abstract Xwt.Size Size { get; }
+ }
+
+ public abstract class CodeLensProvider
+ {
+ internal string MimeType { get; set; }
+
+ public abstract Task<IEnumerable<CodeLens>> GetLenses (TextEditor editor, DocumentContext ctx, CancellationToken token);
+ }
+
+ class CodeLensTextEditorExtension : TextEditorExtension
+ {
+ CancellationTokenSource src = new CancellationTokenSource ();
+ bool isDisposed;
+ static List<CodeLensProvider> codeLensProviders = new List<CodeLensProvider> ();
+
+ static CodeLensTextEditorExtension ()
+ {
+ AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Ide/CodeLensProvider", delegate (object sender, ExtensionNodeEventArgs args) {
+ var node = (MimeTypeExtensionNode)args.ExtensionNode;
+ switch (args.Change) {
+ case ExtensionChange.Add:
+ var matcher = (CodeLensProvider)node.CreateInstance ();
+ matcher.MimeType = node.MimeType;
+ codeLensProviders.Add (matcher);
+ break;
+ case ExtensionChange.Remove:
+ var toRemove = codeLensProviders.FirstOrDefault (m => m.MimeType == node.MimeType);
+ if (toRemove != null)
+ codeLensProviders.Remove (toRemove);
+ break;
+ }
+ });
+ }
+
+ protected override void Initialize ()
+ {
+ DocumentContext.DocumentParsed += DocumentContext_DocumentParsed;
+ }
+
+ public override void Dispose ()
+ {
+ if (isDisposed)
+ return;
+ isDisposed = true;
+ CancelDocumentParsedUpdate ();
+ DocumentContext.DocumentParsed -= DocumentContext_DocumentParsed;
+ base.Dispose ();
+ }
+
+ void CancelDocumentParsedUpdate ()
+ {
+ src.Cancel ();
+ src = new CancellationTokenSource ();
+ }
+
+ void DocumentContext_DocumentParsed (object sender, EventArgs e)
+ {
+ CancelDocumentParsedUpdate ();
+ var token = src.Token;
+ var parsedDocument = DocumentContext.ParsedDocument;
+ if (!isDisposed)
+ UpdateLenses (token);
+ }
+
+ List<ICodeLensMarker> codeLensMarkers = new List<ICodeLensMarker> ();
+ struct CodeLensCacheItem
+ {
+ public ICodeLensMarker Marker { get; set; }
+ public CodeLens Lens { get; set; }
+
+ public CodeLensCacheItem (ICodeLensMarker marker, CodeLens lens)
+ {
+ Marker = marker;
+ Lens = lens;
+ }
+ }
+
+ Dictionary<CodeLensProvider, List<CodeLensCacheItem>> lensCache = new Dictionary<CodeLensProvider, List<CodeLensCacheItem>> ();
+
+ async void UpdateLenses (CancellationToken token = default (CancellationToken))
+ {
+ foreach (var provider in codeLensProviders) {
+ var lenses = await provider.GetLenses (Editor, DocumentContext, token).ConfigureAwait (false);
+ await Runtime.RunInMainThread (delegate {
+ if (lensCache.TryGetValue (provider, out List<CodeLensCacheItem> cache)) {
+ lensCache.Remove (provider);
+ foreach (var item in cache)
+ item.Marker.RemoveLens (item.Lens);
+ }
+
+ var newCache = new List<CodeLensCacheItem> ();
+ foreach (var lens in lenses) {
+ var line = Editor.GetLineByOffset (lens.CodeLensSpan.Offset);
+ var codeLensMarker = Editor.GetLineMarkers (line).OfType<ICodeLensMarker> ().FirstOrDefault ();
+ if (codeLensMarker == null) {
+ codeLensMarker = Editor.TextMarkerFactory.CreateCodeLensMarker (Editor);
+ Editor.AddMarker (line, codeLensMarker);
+ codeLensMarkers.Add (codeLensMarker);
+ }
+ codeLensMarker.AddLens (lens);
+ newCache.Add (new CodeLensCacheItem (codeLensMarker, lens));
+ }
+ lensCache.Add (provider, newCache);
+ });
+ }
+
+ await Runtime.RunInMainThread (delegate {
+ RemoveUnusedCodeLensMarkers ();
+ });
+ }
+
+ void RemoveUnusedCodeLensMarkers ()
+ {
+ foreach (var marker in codeLensMarkers.ToArray ()) {
+ if (marker.CodeLensCount == 0) {
+ Editor.RemoveMarker (marker);
+ codeLensMarkers.Remove (marker);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/ITextLineMarker.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/ITextLineMarker.cs
index 982033e951..34a51d5efe 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/ITextLineMarker.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/ITextLineMarker.cs
@@ -77,4 +77,12 @@ namespace MonoDevelop.Ide.Editor
void AddTask (MonoDevelop.Ide.Tasks.TaskListEntry task);
}
+
+ public interface ICodeLensMarker : ITextLineMarker
+ {
+ int CodeLensCount { get; }
+
+ void AddLens (MonoDevelop.Ide.Editor.Extension.CodeLens lens);
+ void RemoveLens (MonoDevelop.Ide.Editor.Extension.CodeLens lens);
+ }
} \ No newline at end of file
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/InternalExtensionAPI/ITextMarkerFactory.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/InternalExtensionAPI/ITextMarkerFactory.cs
index 95900bc1d4..1581b639a4 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/InternalExtensionAPI/ITextMarkerFactory.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/InternalExtensionAPI/ITextMarkerFactory.cs
@@ -44,6 +44,7 @@ namespace MonoDevelop.Ide.Editor
ITextLineMarker CreateAsmLineMarker (TextEditor editor);
IUnitTestMarker CreateUnitTestMarker (TextEditor editor, UnitTestMarkerHost host, UnitTestLocation unitTestLocation);
IMessageBubbleLineMarker CreateMessageBubbleLineMarker (TextEditor editor);
+ ICodeLensMarker CreateCodeLensMarker (TextEditor editor);
#endregion
#region Segment marker
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
index 9a8a810544..a7e558474b 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
@@ -9460,6 +9460,7 @@
<Compile Include="MonoDevelop.Ide.Projects\LanguageCellRenderer.cs" />
<Compile Include="MonoDevelop.Components\RestartPanel.cs" />
<Compile Include="MonoDevelop.Ide.Gui.OptionPanels\DotNetCompileTargetSelector.cs" />
+ <Compile Include="MonoDevelop.Ide.Editor.Extension\CodeLensTextEditorExtension.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Makefile.am" />