hover method symbol v1
This commit is contained in:
@@ -14,8 +14,8 @@ using Microsoft.CodeAnalysis.MSBuild;
|
|||||||
using Microsoft.CodeAnalysis.Razor.SemanticTokens;
|
using Microsoft.CodeAnalysis.Razor.SemanticTokens;
|
||||||
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
|
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
|
||||||
using Microsoft.CodeAnalysis.Remote.Razor.SemanticTokens;
|
using Microsoft.CodeAnalysis.Remote.Razor.SemanticTokens;
|
||||||
|
using Microsoft.CodeAnalysis.Shared.Utilities;
|
||||||
using Microsoft.CodeAnalysis.Text;
|
using Microsoft.CodeAnalysis.Text;
|
||||||
using NuGet.Packaging;
|
|
||||||
using SharpIDE.Application.Features.Analysis.FixLoaders;
|
using SharpIDE.Application.Features.Analysis.FixLoaders;
|
||||||
using SharpIDE.Application.Features.Analysis.Razor;
|
using SharpIDE.Application.Features.Analysis.Razor;
|
||||||
using SharpIDE.Application.Features.SolutionDiscovery;
|
using SharpIDE.Application.Features.SolutionDiscovery;
|
||||||
@@ -476,6 +476,37 @@ public static class RoslynAnalysis
|
|||||||
return changedFilesWithText;
|
return changedFilesWithText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<ISymbol?> LookupSymbol(SharpIdeFile fileModel, LinePosition linePosition)
|
||||||
|
{
|
||||||
|
await _solutionLoadedTcs.Task;
|
||||||
|
var project = _workspace!.CurrentSolution.Projects.Single(s => s.FilePath == ((IChildSharpIdeNode)fileModel).GetNearestProjectNode()!.FilePath);
|
||||||
|
var document = project.Documents.Single(s => s.FilePath == fileModel.Path);
|
||||||
|
Guard.Against.Null(document, nameof(document));
|
||||||
|
var sourceText = await document.GetTextAsync();
|
||||||
|
var position = sourceText.GetPosition(linePosition);
|
||||||
|
var semanticModel = await document.GetSemanticModelAsync();
|
||||||
|
Guard.Against.Null(semanticModel, nameof(semanticModel));
|
||||||
|
var syntaxRoot = await document.GetSyntaxRootAsync();
|
||||||
|
var node = syntaxRoot!.FindToken(position).Parent!;
|
||||||
|
var symbol = semanticModel.GetSymbolInfo(node).Symbol ?? semanticModel.GetDeclaredSymbol(node);
|
||||||
|
|
||||||
|
if (symbol is null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("No symbol found at position");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var documentationCommentXml = symbol.GetDocumentationCommentXml();
|
||||||
|
if (documentationCommentXml is not null)
|
||||||
|
{
|
||||||
|
var comment = DocumentationComment.FromXmlFragment(documentationCommentXml);
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"Symbol found: {symbol.Name} ({symbol.Kind}) - {symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}");
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
public static void UpdateDocument(SharpIdeFile fileModel, string newContent)
|
public static void UpdateDocument(SharpIdeFile fileModel, string newContent)
|
||||||
{
|
{
|
||||||
Guard.Against.Null(fileModel, nameof(fileModel));
|
Guard.Against.Null(fileModel, nameof(fileModel));
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
<IgnoresAccessChecksTo Include="Microsoft.CodeAnalysis.LanguageServer.Protocol" />
|
<IgnoresAccessChecksTo Include="Microsoft.CodeAnalysis.LanguageServer.Protocol" />
|
||||||
<IgnoresAccessChecksTo Include="Microsoft.CodeAnalysis.ExternalAccess.Razor.Features" />
|
<IgnoresAccessChecksTo Include="Microsoft.CodeAnalysis.ExternalAccess.Razor.Features" />
|
||||||
<IgnoresAccessChecksTo Include="Microsoft.CodeAnalysis.Razor.SemanticTokens" />
|
<IgnoresAccessChecksTo Include="Microsoft.CodeAnalysis.Razor.SemanticTokens" />
|
||||||
|
<IgnoresAccessChecksTo Include="Microsoft.CodeAnalysis.Workspaces" />
|
||||||
|
<IgnoresAccessChecksToExcludeTypeName Include="System.Linq.RoslynEnumerableExtensions" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -146,9 +146,9 @@ public partial class CustomHighlighter : SyntaxHighlighter
|
|||||||
"number" => CachedColors.NumberGreen,
|
"number" => CachedColors.NumberGreen,
|
||||||
|
|
||||||
// Types (User Types)
|
// Types (User Types)
|
||||||
"class name" => CachedColors.ClassBlue,
|
"class name" => CachedColors.ClassGreen,
|
||||||
"record class name" => CachedColors.ClassBlue,
|
"record class name" => CachedColors.ClassGreen,
|
||||||
"struct name" => CachedColors.ClassBlue,
|
"struct name" => CachedColors.ClassGreen,
|
||||||
"interface name" => CachedColors.InterfaceGreen,
|
"interface name" => CachedColors.InterfaceGreen,
|
||||||
"enum name" => CachedColors.InterfaceGreen,
|
"enum name" => CachedColors.InterfaceGreen,
|
||||||
"namespace name" => CachedColors.White,
|
"namespace name" => CachedColors.White,
|
||||||
@@ -188,7 +188,7 @@ public partial class CustomHighlighter : SyntaxHighlighter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file static class CachedColors
|
public static class CachedColors
|
||||||
{
|
{
|
||||||
public static readonly Color Orange = new("f27718");
|
public static readonly Color Orange = new("f27718");
|
||||||
public static readonly Color White = new("dcdcdc");
|
public static readonly Color White = new("dcdcdc");
|
||||||
@@ -198,7 +198,7 @@ file static class CachedColors
|
|||||||
public static readonly Color LightOrangeBrown = new("d69d85");
|
public static readonly Color LightOrangeBrown = new("d69d85");
|
||||||
public static readonly Color NumberGreen = new("b5cea8");
|
public static readonly Color NumberGreen = new("b5cea8");
|
||||||
public static readonly Color InterfaceGreen = new("b8d7a3");
|
public static readonly Color InterfaceGreen = new("b8d7a3");
|
||||||
public static readonly Color ClassBlue = new("4ec9b0");
|
public static readonly Color ClassGreen = new("4ec9b0");
|
||||||
public static readonly Color VariableBlue = new("9cdcfe");
|
public static readonly Color VariableBlue = new("9cdcfe");
|
||||||
public static readonly Color Gray = new("a9a9a9");
|
public static readonly Color Gray = new("a9a9a9");
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[gd_resource type="FontVariation" load_steps=2 format=3 uid="uid://cctwlwcoycek7"]
|
||||||
|
|
||||||
|
[ext_resource type="FontFile" uid="uid://7jc0nj310cu6" path="res://Features/CodeEditor/Resources/CascadiaCode.ttf" id="1_ba3y1"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
base_font = ExtResource("1_ba3y1")
|
||||||
|
spacing_top = 3
|
||||||
|
spacing_bottom = 2
|
||||||
|
baseline_offset = 0.05
|
||||||
@@ -82,12 +82,62 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
|||||||
private void OnSymbolValidate(string symbol)
|
private void OnSymbolValidate(string symbol)
|
||||||
{
|
{
|
||||||
GD.Print($"Symbol validating: {symbol}");
|
GD.Print($"Symbol validating: {symbol}");
|
||||||
|
//var valid = symbol.Contains(' ') is false;
|
||||||
|
//SetSymbolLookupWordAsValid(valid);
|
||||||
SetSymbolLookupWordAsValid(true);
|
SetSymbolLookupWordAsValid(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSymbolHovered(string symbol, long line, long column)
|
private async void OnSymbolHovered(string symbol, long line, long column)
|
||||||
{
|
{
|
||||||
GD.Print($"Symbol hovered: {symbol}");
|
if (HasFocus() is false) return; // only show if we have focus, every tab is currently listening for this event, maybe find a better way
|
||||||
|
GD.Print($"Symbol hovered: {symbol} at line {line}, column {column}");
|
||||||
|
|
||||||
|
var roslynSymbol = await RoslynAnalysis.LookupSymbol(_currentFile, new LinePosition((int)line, (int)column));
|
||||||
|
if (roslynSymbol is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var popupPanel = new PopupPanel();
|
||||||
|
popupPanel.Unfocusable = true; // may need to change eventually for navigating to other symbols
|
||||||
|
popupPanel.MouseExited += () => popupPanel.QueueFree();
|
||||||
|
// set background color
|
||||||
|
|
||||||
|
var styleBox = new StyleBoxFlat
|
||||||
|
{
|
||||||
|
BgColor = new Color("2b2d30"),
|
||||||
|
BorderColor = new Color("3e4045"),
|
||||||
|
BorderWidthTop = 1,
|
||||||
|
BorderWidthBottom = 1,
|
||||||
|
BorderWidthLeft = 1,
|
||||||
|
BorderWidthRight = 1,
|
||||||
|
CornerRadiusBottomLeft = 4,
|
||||||
|
CornerRadiusBottomRight = 4,
|
||||||
|
CornerRadiusTopLeft = 4,
|
||||||
|
CornerRadiusTopRight = 4,
|
||||||
|
ShadowSize = 2,
|
||||||
|
ShadowColor = new Color(0, 0, 0, 0.5f),
|
||||||
|
ContentMarginTop = 10,
|
||||||
|
ContentMarginBottom = 10,
|
||||||
|
ContentMarginLeft = 10,
|
||||||
|
ContentMarginRight = 10
|
||||||
|
};
|
||||||
|
popupPanel.AddThemeStyleboxOverride("panel", styleBox);
|
||||||
|
|
||||||
|
var symbolInfoNode = roslynSymbol switch
|
||||||
|
{
|
||||||
|
IMethodSymbol methodSymbol => SymbolInfoComponents.GetMethodSymbolInfo(methodSymbol),
|
||||||
|
_ => new Control()
|
||||||
|
};
|
||||||
|
popupPanel.AddChild(symbolInfoNode);
|
||||||
|
AddChild(popupPanel);
|
||||||
|
|
||||||
|
var globalSymbolPosition = GetRectAtLineColumn((int)line, (int)column).Position + GetGlobalPosition();
|
||||||
|
globalSymbolPosition.Y += GetLineHeight();
|
||||||
|
|
||||||
|
var globalMousePosition = GetGlobalMousePosition();
|
||||||
|
popupPanel.Position = new Vector2I((int)globalMousePosition.X, (int)globalSymbolPosition.Y);
|
||||||
|
popupPanel.Popup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCaretChanged()
|
private void OnCaretChanged()
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
[gd_scene load_steps=6 format=3 uid="uid://cinaqbdghcvoi"]
|
[gd_scene load_steps=5 format=3 uid="uid://cinaqbdghcvoi"]
|
||||||
|
|
||||||
[ext_resource type="FontFile" uid="uid://7jc0nj310cu6" path="res://Features/CodeEditor/Resources/CascadiaCode.ttf" id="1_s7ira"]
|
[ext_resource type="FontVariation" uid="uid://cctwlwcoycek7" path="res://Features/CodeEditor/Resources/CascadiaFontVariation.tres" id="1_s7ira"]
|
||||||
[ext_resource type="Script" uid="uid://du2lt7r1p1qfy" path="res://Features/CodeEditor/SharpIdeCodeEdit.cs" id="2_kp2fd"]
|
[ext_resource type="Script" uid="uid://du2lt7r1p1qfy" path="res://Features/CodeEditor/SharpIdeCodeEdit.cs" id="2_kp2fd"]
|
||||||
|
|
||||||
[sub_resource type="FontVariation" id="FontVariation_y3aoi"]
|
|
||||||
base_font = ExtResource("1_s7ira")
|
|
||||||
spacing_top = 3
|
|
||||||
spacing_bottom = 2
|
|
||||||
baseline_offset = 0.05
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_v06ln"]
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_v06ln"]
|
||||||
content_margin_left = 4.0
|
content_margin_left = 4.0
|
||||||
content_margin_top = 4.0
|
content_margin_top = 4.0
|
||||||
@@ -26,7 +20,7 @@ corner_detail = 5
|
|||||||
|
|
||||||
[node name="SharpIdeCodeEdit" type="CodeEdit"]
|
[node name="SharpIdeCodeEdit" type="CodeEdit"]
|
||||||
theme_override_colors/current_line_color = Color(0.0588235, 0.0588235, 0.0588235, 1)
|
theme_override_colors/current_line_color = Color(0.0588235, 0.0588235, 0.0588235, 1)
|
||||||
theme_override_fonts/font = SubResource("FontVariation_y3aoi")
|
theme_override_fonts/font = ExtResource("1_s7ira")
|
||||||
theme_override_font_sizes/font_size = 18
|
theme_override_font_sizes/font_size = 18
|
||||||
theme_override_styles/normal = SubResource("StyleBoxFlat_v06ln")
|
theme_override_styles/normal = SubResource("StyleBoxFlat_v06ln")
|
||||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_7ptyn")
|
theme_override_styles/focus = SubResource("StyleBoxEmpty_7ptyn")
|
||||||
|
|||||||
276
src/SharpIDE.Godot/Features/CodeEditor/SymbolInfoComponents.cs
Normal file
276
src/SharpIDE.Godot/Features/CodeEditor/SymbolInfoComponents.cs
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
using Godot;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace SharpIDE.Godot.Features.CodeEditor;
|
||||||
|
|
||||||
|
public static class SymbolInfoComponents
|
||||||
|
{
|
||||||
|
private static readonly FontVariation MonospaceFont = ResourceLoader.Load<FontVariation>("uid://cctwlwcoycek7");
|
||||||
|
public static RichTextLabel GetMethodSymbolInfo(IMethodSymbol methodSymbol)
|
||||||
|
{
|
||||||
|
var label = new RichTextLabel();
|
||||||
|
label.FitContent = true;
|
||||||
|
label.AutowrapMode = TextServer.AutowrapMode.Off;
|
||||||
|
label.SetAnchorsPreset(Control.LayoutPreset.FullRect);
|
||||||
|
label.PushFont(MonospaceFont);
|
||||||
|
label.PushColor(CachedColors.KeywordBlue);
|
||||||
|
label.AddText(methodSymbol.DeclaredAccessibility.GetAccessibilityString());
|
||||||
|
label.Pop();
|
||||||
|
label.AddText(" ");
|
||||||
|
label.AddStaticModifier(methodSymbol);
|
||||||
|
label.AddText(" ");
|
||||||
|
label.AddMethodReturnType(methodSymbol);
|
||||||
|
label.AddText(" ");
|
||||||
|
label.AddMethodName(methodSymbol);
|
||||||
|
label.AddTypeParameters(methodSymbol);
|
||||||
|
label.AddText("(");
|
||||||
|
label.AddParameters(methodSymbol);
|
||||||
|
label.AddText(")");
|
||||||
|
label.Newline();
|
||||||
|
label.AddText("in class ");
|
||||||
|
label.AddContainingNamespaceAndClass(methodSymbol);
|
||||||
|
label.Newline(); // TODO: Make this only 1.5 lines high
|
||||||
|
label.Newline(); //
|
||||||
|
label.AddTypeParameterArguments(methodSymbol);
|
||||||
|
label.AddHr(100, 1, CachedColors.Gray);
|
||||||
|
label.Newline();
|
||||||
|
label.Pop(); // font
|
||||||
|
label.AddText("docs");
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetAccessibilityString(this Accessibility accessibility) => accessibility switch
|
||||||
|
{
|
||||||
|
Accessibility.Public => "public",
|
||||||
|
Accessibility.Private => "private",
|
||||||
|
Accessibility.Protected => "protected",
|
||||||
|
Accessibility.Internal => "internal",
|
||||||
|
Accessibility.ProtectedOrInternal => "protected internal",
|
||||||
|
Accessibility.ProtectedAndInternal => "private protected",
|
||||||
|
_ => "unknown"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static void AddStaticModifier(this RichTextLabel label, IMethodSymbol methodSymbol)
|
||||||
|
{
|
||||||
|
if (methodSymbol.IsStatic || methodSymbol.ReducedFrom?.IsStatic is true)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.KeywordBlue);
|
||||||
|
label.AddText("static");
|
||||||
|
label.Pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddMethodReturnType(this RichTextLabel label, IMethodSymbol methodSymbol)
|
||||||
|
{
|
||||||
|
if (methodSymbol.ReturnsVoid)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.KeywordBlue);
|
||||||
|
label.AddText("void");
|
||||||
|
label.Pop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.PushColor(CachedColors.ClassGreen);
|
||||||
|
label.AddText(methodSymbol.ReturnType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
|
||||||
|
label.Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddMethodName(this RichTextLabel label, IMethodSymbol methodSymbol)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.Yellow);
|
||||||
|
label.AddText(methodSymbol.Name);
|
||||||
|
label.Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddTypeParameters(this RichTextLabel label, IMethodSymbol methodSymbol)
|
||||||
|
{
|
||||||
|
if (methodSymbol.TypeParameters.Length == 0) return;
|
||||||
|
label.PushColor(CachedColors.White);
|
||||||
|
label.AddText("<");
|
||||||
|
label.Pop();
|
||||||
|
foreach (var (index, typeParameter) in methodSymbol.TypeParameters.Index())
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.ClassGreen);
|
||||||
|
label.AddText(typeParameter.Name);
|
||||||
|
label.Pop();
|
||||||
|
if (index < methodSymbol.TypeParameters.Length - 1)
|
||||||
|
{
|
||||||
|
label.AddText(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label.PushColor(CachedColors.White);
|
||||||
|
label.AddText(">");
|
||||||
|
label.Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddParameters(this RichTextLabel label, IMethodSymbol methodSymbol)
|
||||||
|
{
|
||||||
|
if (methodSymbol.IsExtensionMethod)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.KeywordBlue);
|
||||||
|
label.AddText("this");
|
||||||
|
label.Pop();
|
||||||
|
label.AddText(" ");
|
||||||
|
}
|
||||||
|
foreach (var (index, parameterSymbol) in methodSymbol.Parameters.Index())
|
||||||
|
{
|
||||||
|
var attributes = parameterSymbol.GetAttributes();
|
||||||
|
if (attributes.Length is not 0)
|
||||||
|
{
|
||||||
|
foreach (var (attrIndex, attribute) in attributes.Index())
|
||||||
|
{
|
||||||
|
label.AddText("[");
|
||||||
|
label.PushColor(CachedColors.ClassGreen);
|
||||||
|
var displayString = attribute.AttributeClass?.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
|
||||||
|
if (displayString?.EndsWith("Attribute") is true) displayString = displayString[..^9]; // remove last 9 chars
|
||||||
|
label.AddText(displayString ?? "unknown");
|
||||||
|
label.Pop();
|
||||||
|
label.AddText("]");
|
||||||
|
label.AddText(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parameterSymbol.RefKind != RefKind.None) // ref, in, out
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.KeywordBlue);
|
||||||
|
label.AddText(parameterSymbol.RefKind.ToString().ToLower());
|
||||||
|
label.Pop();
|
||||||
|
label.AddText(" ");
|
||||||
|
}
|
||||||
|
else if (parameterSymbol.IsParams)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.KeywordBlue);
|
||||||
|
label.AddText("params");
|
||||||
|
label.Pop();
|
||||||
|
label.AddText(" ");
|
||||||
|
}
|
||||||
|
label.PushColor(parameterSymbol.Type.GetSymbolColourByType());
|
||||||
|
label.AddText(parameterSymbol.Type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
|
||||||
|
label.Pop();
|
||||||
|
label.AddText(" ");
|
||||||
|
label.PushColor(CachedColors.VariableBlue);
|
||||||
|
label.AddText(parameterSymbol.Name);
|
||||||
|
label.Pop();
|
||||||
|
// default value
|
||||||
|
if (parameterSymbol.HasExplicitDefaultValue)
|
||||||
|
{
|
||||||
|
label.AddText(" = ");
|
||||||
|
if (parameterSymbol.ExplicitDefaultValue is null)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.KeywordBlue);
|
||||||
|
label.AddText("null");
|
||||||
|
label.Pop();
|
||||||
|
}
|
||||||
|
else if (parameterSymbol.Type.TypeKind == TypeKind.Enum)
|
||||||
|
{
|
||||||
|
var explicitDefaultValue = parameterSymbol.ExplicitDefaultValue;
|
||||||
|
// Find the enum field with the same constant value
|
||||||
|
var enumMember = parameterSymbol.Type.GetMembers()
|
||||||
|
.OfType<IFieldSymbol>()
|
||||||
|
.FirstOrDefault(f => f.HasConstantValue && Equals(f.ConstantValue, explicitDefaultValue));
|
||||||
|
|
||||||
|
if (enumMember != null)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.InterfaceGreen);
|
||||||
|
label.AddText(parameterSymbol.Type.Name);
|
||||||
|
label.Pop();
|
||||||
|
label.PushColor(CachedColors.White);
|
||||||
|
label.AddText(".");
|
||||||
|
label.Pop();
|
||||||
|
label.PushColor(CachedColors.White);
|
||||||
|
label.AddText(enumMember.Name);
|
||||||
|
label.Pop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.InterfaceGreen);
|
||||||
|
label.AddText(parameterSymbol.Type.Name);
|
||||||
|
label.Pop();
|
||||||
|
label.AddText($"({explicitDefaultValue})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parameterSymbol.ExplicitDefaultValue is string str)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.LightOrangeBrown);
|
||||||
|
label.AddText($"""
|
||||||
|
"{str}"
|
||||||
|
""");
|
||||||
|
label.Pop();
|
||||||
|
}
|
||||||
|
else if (parameterSymbol.ExplicitDefaultValue is bool b)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.KeywordBlue);
|
||||||
|
label.AddText(b ? "true" : "false");
|
||||||
|
label.Pop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
label.AddText(parameterSymbol.ExplicitDefaultValue.ToString() ?? "unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < methodSymbol.Parameters.Length - 1)
|
||||||
|
{
|
||||||
|
label.AddText(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddContainingNamespaceAndClass(this RichTextLabel label, IMethodSymbol methodSymbol)
|
||||||
|
{
|
||||||
|
if (methodSymbol.ContainingNamespace is null || methodSymbol.ContainingNamespace.IsGlobalNamespace) return;
|
||||||
|
var namespaces = methodSymbol.ContainingNamespace.ToDisplayString().Split('.');
|
||||||
|
foreach (var ns in namespaces)
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.KeywordBlue);
|
||||||
|
label.AddText(ns);
|
||||||
|
label.Pop();
|
||||||
|
label.AddText(".");
|
||||||
|
}
|
||||||
|
label.PushColor(CachedColors.ClassGreen);
|
||||||
|
label.AddText(methodSymbol.ContainingType.Name);
|
||||||
|
label.Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddTypeParameterArguments(this RichTextLabel label, IMethodSymbol methodSymbol)
|
||||||
|
{
|
||||||
|
if (methodSymbol.TypeArguments.Length == 0) return;
|
||||||
|
var typeParameters = methodSymbol.TypeParameters;
|
||||||
|
var typeArguments = methodSymbol.TypeArguments;
|
||||||
|
if (typeParameters.Length != typeArguments.Length) throw new Exception("Type parameters and type arguments length mismatch.");
|
||||||
|
foreach (var (index, (typeArgument, typeParameter)) in methodSymbol.TypeArguments.Zip(typeParameters).Index())
|
||||||
|
{
|
||||||
|
label.PushColor(CachedColors.ClassGreen);
|
||||||
|
label.AddText(typeParameter.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
|
||||||
|
label.Pop();
|
||||||
|
label.AddText(" is ");
|
||||||
|
label.PushColor(typeArgument.GetSymbolColourByType());
|
||||||
|
label.AddText(typeArgument.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
|
||||||
|
label.Pop();
|
||||||
|
if (index < methodSymbol.TypeArguments.Length - 1)
|
||||||
|
{
|
||||||
|
label.Newline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle arrays etc, where there are multiple colours in one type
|
||||||
|
private static Color GetSymbolColourByType(this ITypeSymbol symbol)
|
||||||
|
{
|
||||||
|
Color colour = symbol switch
|
||||||
|
{
|
||||||
|
{SpecialType: not SpecialType.None} => CachedColors.KeywordBlue,
|
||||||
|
INamedTypeSymbol namedTypeSymbol => namedTypeSymbol.TypeKind switch
|
||||||
|
{
|
||||||
|
TypeKind.Class => CachedColors.ClassGreen,
|
||||||
|
TypeKind.Interface => CachedColors.InterfaceGreen,
|
||||||
|
TypeKind.Struct => CachedColors.ClassGreen,
|
||||||
|
TypeKind.Enum => CachedColors.InterfaceGreen,
|
||||||
|
TypeKind.Delegate => CachedColors.ClassGreen,
|
||||||
|
_ => CachedColors.Orange
|
||||||
|
},
|
||||||
|
_ => CachedColors.Orange
|
||||||
|
};
|
||||||
|
return colour;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://c48r2nff1ckv
|
||||||
Reference in New Issue
Block a user