/*
Copyright (C) 2014-2019 de4dot@gmail.com
This file is part of dnSpy
dnSpy is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
dnSpy is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with dnSpy. If not, see .
*/
using System;
using System.Collections.Generic;
using dnSpy.Contracts.Images;
using dnSpy.Contracts.Metadata;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
namespace dnSpy.Contracts.Text.Editor {
///
/// Text marker location base class
///
public abstract class GlyphTextMarkerLocationInfo {
}
///
/// Method text marker location info
///
public sealed class DotNetMethodBodyGlyphTextMarkerLocationInfo : GlyphTextMarkerLocationInfo {
///
/// Module
///
public ModuleId Module { get; }
///
/// Token of method
///
public uint Token { get; }
///
/// Method offset
///
public uint ILOffset { get; }
///
/// Constructor
///
/// Module
/// Token of method
/// Method offset
public DotNetMethodBodyGlyphTextMarkerLocationInfo(ModuleId module, uint token, uint ilOffset) {
Module = module;
Token = token;
ILOffset = ilOffset;
}
///
/// Constructor
///
/// Module
/// Token of method
/// Method offset
public DotNetMethodBodyGlyphTextMarkerLocationInfo(ModuleId module, int token, uint ilOffset) {
Module = module;
Token = (uint)token;
ILOffset = ilOffset;
}
}
///
/// Method text marker location info
///
public sealed class DotNetTokenGlyphTextMarkerLocationInfo : GlyphTextMarkerLocationInfo {
///
/// Module
///
public ModuleId Module { get; }
///
/// Token of definition (type, method, field, property, event)
///
public uint Token { get; }
///
/// Constructor
///
/// Module
/// Token of definition (type, method, field, property, event)
public DotNetTokenGlyphTextMarkerLocationInfo(ModuleId module, uint token) {
Module = module;
Token = token;
}
///
/// Constructor
///
/// Module
/// Token of definition (type, method, field, property, event)
public DotNetTokenGlyphTextMarkerLocationInfo(ModuleId module, int token) {
Module = module;
Token = (uint)token;
}
}
///
/// Marks text and shows a glyph in the glyph margin
///
public interface IGlyphTextMarkerService {
///
/// Should be called whenever gets a new
///
/// Text view
/// New map or null if none
void SetDotNetSpanMap(ITextView textView, IDotNetSpanMap? map);
///
/// Adds a marker
///
/// Method token
/// Method offset
/// Image shown in the glyph margin or null if none
/// Name of a (or an ) or null. It should have a background color and an optional foreground color for the border
/// Name of a or null. It's used whenever the caret is inside the text marker.
/// Classification type or null. Only the foreground color is needed. If it has a background color, it will hide the text markers shown in the text marker layer (eg. search result, highlighted reference)
/// Z-index of and , eg.
/// User data
/// Glyph handler or null
/// Filters out non-supported text views
///
IGlyphTextMethodMarker AddMarker(ModuleTokenId tokenId, uint ilOffset, ImageReference? glyphImage, string? markerTypeName, string? selectedMarkerTypeName, IClassificationType? classificationType, int zIndex, object? tag = null, IGlyphTextMarkerHandler? handler = null, Func? textViewFilter = null);
///
/// Adds a marker
///
/// Location
/// Image shown in the glyph margin or null if none
/// Name of a (or an ) or null. It should have a background color and an optional foreground color for the border
/// Name of a or null. It's used whenever the caret is inside the text marker.
/// Classification type or null. Only the foreground color is needed. If it has a background color, it will hide the text markers shown in the text marker layer (eg. search result, highlighted reference)
/// Z-index of and , eg.
/// User data
/// Glyph handler or null
/// Filters out non-supported text views
///
IGlyphTextMarker AddMarker(GlyphTextMarkerLocationInfo location, ImageReference? glyphImage, string? markerTypeName, string? selectedMarkerTypeName, IClassificationType? classificationType, int zIndex, object? tag = null, IGlyphTextMarkerHandler? handler = null, Func? textViewFilter = null);
///
/// Removes a marker
///
/// Marker to remove
void Remove(IGlyphTextMarker marker);
///
/// Removes markers
///
/// Markers to remove
void Remove(IEnumerable markers);
///
/// Gets markers
///
/// Text view
/// Span
///
GlyphTextMarkerAndSpan[] GetMarkers(ITextView textView, SnapshotSpan span);
}
///
/// Marker and its span in a
///
public readonly struct GlyphTextMarkerAndSpan {
///
/// Gets the marker
///
public IGlyphTextMarker Marker { get; }
///
/// Gets the span of the marker in the
///
public SnapshotSpan Span { get; }
///
/// Constructor
///
/// Marker
/// Span of the marker in the
public GlyphTextMarkerAndSpan(IGlyphTextMarker marker, SnapshotSpan span) {
if (span.Snapshot is null)
throw new ArgumentException();
Marker = marker ?? throw new ArgumentNullException(nameof(marker));
Span = span;
}
}
///
/// A marker created by
///
public interface IGlyphTextMarker {
///
/// Gets the image reference shown in the glyph margin or null if none
///
ImageReference? GlyphImageReference { get; }
///
/// Gets the name of the marker format definition or null if none
///
string? MarkerTypeName { get; }
///
/// Gets the name of the marker format definition to use whenever the caret is inside the span; it can be null
///
string? SelectedMarkerTypeName { get; }
///
/// Gets the classification type or null if none
///
IClassificationType? ClassificationType { get; }
///
/// Gets the z-index of and , eg.
///
int ZIndex { get; }
///
/// Gets the user data
///
object? Tag { get; }
}
///
/// A method marker created by
///
public interface IGlyphTextMethodMarker : IGlyphTextMarker {
///
/// Gets the method token
///
ModuleTokenId Method { get; }
///
/// Gets the IL offset
///
uint ILOffset { get; }
}
///
/// A method marker created by
///
public interface IGlyphTextDotNetTokenMarker : IGlyphTextMarker {
///
/// Gets the module
///
ModuleId Module { get; }
///
/// Gets the token
///
uint Token { get; }
}
///
/// Converts .NET tokens to spans
///
public interface IDotNetSpanMap {
///
/// Converts a method offset to a or returns null if the IL offset isn't present in the document
///
/// Module
/// Token of method
/// IL offset
///
Span? ToSpan(ModuleId module, uint token, uint ilOffset);
///
/// Converts a .NET module + token to a or returns null if the definition isn't present in the document
///
/// Module
/// Token of definition (type, method, field, property, event)
///
Span? ToSpan(ModuleId module, uint token);
}
///
/// text marker tag
///
public interface IGlyphTextMarkerTag : ITag {
///
/// Name of a (or an ) ()
///
string MarkerTypeName { get; }
///
/// Gets the name of the marker format definition to use whenever the caret is inside the span; it can be null ()
///
string? SelectedMarkerTypeName { get; }
///
/// Gets the Z-index ()
///
int ZIndex { get; }
}
///
/// text marker tag
///
public sealed class GlyphTextMarkerTag : IGlyphTextMarkerTag {
///
/// Name of a (or an ) ()
///
public string MarkerTypeName { get; }
///
/// Gets the name of the marker format definition to use whenever the caret is inside the span; it can be null ()
///
public string? SelectedMarkerTypeName { get; }
///
/// Gets the Z-index ()
///
public int ZIndex { get; }
///
/// Constructor
///
/// Name of a (or an ) ()
/// Name of a (or an ) ()
/// Z-index of this text marker ()
public GlyphTextMarkerTag(string markerTypeName, string? selectedMarkerTypeName, int zIndex) {
MarkerTypeName = markerTypeName ?? throw new ArgumentNullException(nameof(markerTypeName));
SelectedMarkerTypeName = selectedMarkerTypeName;
ZIndex = zIndex;
}
}
///
/// glyph tag
///
public interface IGlyphTextMarkerGlyphTag : IGlyphTag {
///
/// Gets the image reference ()
///
ImageReference ImageReference { get; }
///
/// Gets the Z-index ()
///
int ZIndex { get; }
}
///
/// glyph tag
///
public sealed class GlyphTextMarkerGlyphTag : IGlyphTag {
///
/// Image reference ()
///
public ImageReference ImageReference { get; }
///
/// Z-index ()
///
public int ZIndex { get; }
///
/// Constructor
///
/// Image reference ()
/// Z-index ()
public GlyphTextMarkerGlyphTag(ImageReference imageReference, int zIndex) {
ImageReference = imageReference;
ZIndex = zIndex;
}
}
}