Auto size symbol lookup popup
This commit is contained in:
@@ -667,12 +667,30 @@ public class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService buildSe
|
|||||||
return changedFilesWithText;
|
return changedFilesWithText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ISymbol?> GetEnclosingSymbolForReferenceLocation(ReferenceLocation referenceLocation)
|
public record IdeReferenceLocationResult(ReferenceLocation ReferenceLocation, SharpIdeFile? File, ISymbol? EnclosingSymbol);
|
||||||
|
public async Task<IdeReferenceLocationResult?> GetIdeReferenceLocationResult(ReferenceLocation referenceLocation)
|
||||||
{
|
{
|
||||||
var semanticModel = await referenceLocation.Document.GetSemanticModelAsync();
|
var semanticModel = await referenceLocation.Document.GetSemanticModelAsync();
|
||||||
if (semanticModel is null) return null;
|
if (semanticModel is null) return null;
|
||||||
var enclosingSymbol = ReferenceLocationExtensions.GetEnclosingMethodOrPropertyOrField(semanticModel, referenceLocation);
|
var enclosingSymbol = ReferenceLocationExtensions.GetEnclosingMethodOrPropertyOrField(semanticModel, referenceLocation);
|
||||||
return enclosingSymbol;
|
var lineSpan = referenceLocation.Location.GetMappedLineSpan();
|
||||||
|
var file = _sharpIdeSolutionModel!.AllFiles.SingleOrDefault(f => f.Path == lineSpan.Path);
|
||||||
|
var result = new IdeReferenceLocationResult(referenceLocation, file!, enclosingSymbol);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ImmutableArray<IdeReferenceLocationResult>> GetIdeReferenceLocationResults(ImmutableArray<ReferenceLocation> referenceLocations)
|
||||||
|
{
|
||||||
|
var results = new List<IdeReferenceLocationResult>();
|
||||||
|
foreach (var referenceLocation in referenceLocations)
|
||||||
|
{
|
||||||
|
var result = await GetIdeReferenceLocationResult(referenceLocation);
|
||||||
|
if (result is not null)
|
||||||
|
{
|
||||||
|
results.Add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results.ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ImmutableArray<ReferencedSymbol>> FindAllSymbolReferences(ISymbol symbol, CancellationToken cancellationToken = default)
|
public async Task<ImmutableArray<ReferencedSymbol>> FindAllSymbolReferences(ISymbol symbol, CancellationToken cancellationToken = default)
|
||||||
@@ -682,7 +700,7 @@ public class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService buildSe
|
|||||||
|
|
||||||
var solution = _workspace!.CurrentSolution;
|
var solution = _workspace!.CurrentSolution;
|
||||||
var references = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken);
|
var references = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken);
|
||||||
return references.AsImmutable();
|
return references.ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(ISymbol?, LinePositionSpan?, TokenSemanticInfo?)> LookupSymbolSemanticInfo(SharpIdeFile fileModel, LinePosition linePosition)
|
public async Task<(ISymbol?, LinePositionSpan?, TokenSemanticInfo?)> LookupSymbolSemanticInfo(SharpIdeFile fileModel, LinePosition linePosition)
|
||||||
|
|||||||
@@ -48,20 +48,15 @@ public partial class SharpIdeCodeEdit
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Show popup to select which reference to go to
|
// Show popup to select which reference to go to
|
||||||
var scene = _symbolUsagePopupScene.Instantiate<SymbolLookupPopup>();
|
var symbolLookupPopup = _symbolUsagePopupScene.Instantiate<SymbolLookupPopup>();
|
||||||
var locationsAndFiles = locations.Select(s =>
|
var ideReferenceLocationResults = await _roslynAnalysis.GetIdeReferenceLocationResults(locations);
|
||||||
{
|
symbolLookupPopup.IdeReferenceLocationResults = ideReferenceLocationResults;
|
||||||
var lineSpan = s.Location.GetMappedLineSpan();
|
symbolLookupPopup.Symbol = semanticInfo.Value.DeclaredSymbol;
|
||||||
var file = Solution!.AllFiles.SingleOrDefault(f => f.Path == lineSpan.Path);
|
symbolLookupPopup.Size = new Vector2I(1, 1); // Set tiny size so it autosizes up based on child content
|
||||||
return (s, file);
|
|
||||||
}).Where(t => t.file is not null).ToImmutableArray();
|
|
||||||
scene.Locations = locations;
|
|
||||||
scene.LocationsAndFiles = locationsAndFiles!;
|
|
||||||
scene.Symbol = semanticInfo.Value.DeclaredSymbol;
|
|
||||||
await this.InvokeAsync(() =>
|
await this.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
AddChild(scene);
|
AddChild(symbolLookupPopup);
|
||||||
scene.PopupCenteredClamped();
|
symbolLookupPopup.PopupCentered();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System.Collections.Immutable;
|
|||||||
using Godot;
|
using Godot;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.FindSymbols;
|
using Microsoft.CodeAnalysis.FindSymbols;
|
||||||
|
using SharpIDE.Application.Features.Analysis;
|
||||||
using SharpIDE.Application.Features.SolutionDiscovery;
|
using SharpIDE.Application.Features.SolutionDiscovery;
|
||||||
|
|
||||||
namespace SharpIDE.Godot.Features.SymbolLookup;
|
namespace SharpIDE.Godot.Features.SymbolLookup;
|
||||||
@@ -10,8 +11,8 @@ public partial class SymbolLookupPopup : PopupPanel
|
|||||||
{
|
{
|
||||||
private Label _symbolNameLabel = null!;
|
private Label _symbolNameLabel = null!;
|
||||||
private VBoxContainer _usagesContainer = null!;
|
private VBoxContainer _usagesContainer = null!;
|
||||||
public ImmutableArray<ReferenceLocation> Locations { get; set; }
|
|
||||||
public ImmutableArray<(ReferenceLocation location, SharpIdeFile file)> LocationsAndFiles { get; set; }
|
public ImmutableArray<RoslynAnalysis.IdeReferenceLocationResult> IdeReferenceLocationResults { get; set; }
|
||||||
public ISymbol Symbol { get; set; } = null!;
|
public ISymbol Symbol { get; set; } = null!;
|
||||||
private readonly PackedScene _symbolUsageScene = ResourceLoader.Load<PackedScene>("uid://dokm0dyac2enh");
|
private readonly PackedScene _symbolUsageScene = ResourceLoader.Load<PackedScene>("uid://dokm0dyac2enh");
|
||||||
|
|
||||||
@@ -24,11 +25,12 @@ public partial class SymbolLookupPopup : PopupPanel
|
|||||||
AboutToPopup += OnAboutToPopup;
|
AboutToPopup += OnAboutToPopup;
|
||||||
|
|
||||||
_usagesContainer.GetChildren().ToList().ForEach(s => s.QueueFree());
|
_usagesContainer.GetChildren().ToList().ForEach(s => s.QueueFree());
|
||||||
foreach (var (location, file) in LocationsAndFiles)
|
foreach (var result in IdeReferenceLocationResults)
|
||||||
{
|
{
|
||||||
var resultNode = _symbolUsageScene.Instantiate<SymbolUsageComponent>();
|
var resultNode = _symbolUsageScene.Instantiate<SymbolUsageComponent>();
|
||||||
resultNode.Location = location;
|
resultNode.Location = result.ReferenceLocation;
|
||||||
resultNode.File = file;
|
resultNode.File = result.File;
|
||||||
|
resultNode.EnclosingSymbol = result.EnclosingSymbol;
|
||||||
resultNode.ParentSearchWindow = this;
|
resultNode.ParentSearchWindow = this;
|
||||||
_usagesContainer.AddChild(resultNode);
|
_usagesContainer.AddChild(resultNode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ shadow_size = 4
|
|||||||
|
|
||||||
[node name="SymbolLookupPopup" type="PopupPanel"]
|
[node name="SymbolLookupPopup" type="PopupPanel"]
|
||||||
oversampling_override = 1.0
|
oversampling_override = 1.0
|
||||||
size = Vector2i(505, 340)
|
size = Vector2i(564, 340)
|
||||||
visible = true
|
visible = true
|
||||||
theme_override_styles/panel = SubResource("StyleBoxFlat_cuaw5")
|
theme_override_styles/panel = SubResource("StyleBoxFlat_cuaw5")
|
||||||
script = ExtResource("1_f5udm")
|
script = ExtResource("1_f5udm")
|
||||||
@@ -50,15 +50,10 @@ unique_name_in_owner = true
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "'UseWebApi()'"
|
text = "'UseWebApi()'"
|
||||||
|
|
||||||
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/VBoxContainer"]
|
[node name="UsagesVBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer"]
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
follow_focus = true
|
|
||||||
|
|
||||||
[node name="UsagesVBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer"]
|
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
[node name="SymbolUsageComponent" parent="MarginContainer/VBoxContainer/ScrollContainer/UsagesVBoxContainer" instance=ExtResource("1_k5g0h")]
|
[node name="SymbolUsageComponent" parent="MarginContainer/VBoxContainer/UsagesVBoxContainer" instance=ExtResource("1_k5g0h")]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.FindSymbols;
|
using Microsoft.CodeAnalysis.FindSymbols;
|
||||||
using SharpIDE.Application.Features.Analysis;
|
using SharpIDE.Application.Features.Analysis;
|
||||||
using SharpIDE.Application.Features.SolutionDiscovery;
|
using SharpIDE.Application.Features.SolutionDiscovery;
|
||||||
@@ -14,9 +15,8 @@ public partial class SymbolUsageComponent : MarginContainer
|
|||||||
|
|
||||||
public SymbolLookupPopup ParentSearchWindow { get; set; } = null!;
|
public SymbolLookupPopup ParentSearchWindow { get; set; } = null!;
|
||||||
public ReferenceLocation? Location { get; set; }
|
public ReferenceLocation? Location { get; set; }
|
||||||
public SharpIdeFile File { get; set; } = null!;
|
public ISymbol? EnclosingSymbol { get; set; } = null!;
|
||||||
|
public SharpIdeFile? File { get; set; } = null!;
|
||||||
[Inject] private readonly RoslynAnalysis _roslynAnalysis = null!;
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
@@ -32,7 +32,10 @@ public partial class SymbolUsageComponent : MarginContainer
|
|||||||
{
|
{
|
||||||
var mappedLineSpan = Location!.Value.Location.GetMappedLineSpan();
|
var mappedLineSpan = Location!.Value.Location.GetMappedLineSpan();
|
||||||
var fileLinePosition = new SharpIdeFileLinePosition { Line = mappedLineSpan.StartLinePosition.Line, Column = mappedLineSpan.StartLinePosition.Character };
|
var fileLinePosition = new SharpIdeFileLinePosition { Line = mappedLineSpan.StartLinePosition.Line, Column = mappedLineSpan.StartLinePosition.Character };
|
||||||
GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelFireAndForget(File, fileLinePosition);
|
if (File is not null)
|
||||||
|
{
|
||||||
|
GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelFireAndForget(File, fileLinePosition);
|
||||||
|
}
|
||||||
ParentSearchWindow.Hide();
|
ParentSearchWindow.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,13 +44,8 @@ public partial class SymbolUsageComponent : MarginContainer
|
|||||||
if (result is null) return;
|
if (result is null) return;
|
||||||
var mappedLineSpan = result.Value.Location.GetMappedLineSpan();
|
var mappedLineSpan = result.Value.Location.GetMappedLineSpan();
|
||||||
|
|
||||||
_fileNameLabel.Text = File.Name;
|
_fileNameLabel.Text = File?.Name ?? Path.GetFileName(mappedLineSpan.Path);
|
||||||
_lineNumberLabel.Text = (mappedLineSpan.StartLinePosition.Line + 1).ToString();
|
_lineNumberLabel.Text = (mappedLineSpan.StartLinePosition.Line + 1).ToString();
|
||||||
|
_enclosingSymbolLabel.Text = EnclosingSymbol?.Name;
|
||||||
_ = Task.GodotRun(async () =>
|
|
||||||
{
|
|
||||||
var enclosingSymbol = await _roslynAnalysis.GetEnclosingSymbolForReferenceLocation(result.Value);
|
|
||||||
await this.InvokeAsync(() => _enclosingSymbolLabel.Text = enclosingSymbol?.Name);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,33 +29,32 @@ layout_mode = 2
|
|||||||
theme_override_styles/normal = SubResource("StyleBoxFlat_6ov2c")
|
theme_override_styles/normal = SubResource("StyleBoxFlat_6ov2c")
|
||||||
theme_override_styles/focus = SubResource("StyleBoxFlat_dtmd4")
|
theme_override_styles/focus = SubResource("StyleBoxFlat_dtmd4")
|
||||||
|
|
||||||
[node name="MarginContainer" type="MarginContainer" parent="Button"]
|
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||||
layout_mode = 1
|
layout_mode = 2
|
||||||
anchors_preset = 15
|
mouse_filter = 0
|
||||||
anchor_right = 1.0
|
mouse_behavior_recursive = 1
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
theme_override_constants/margin_left = 5
|
theme_override_constants/margin_left = 5
|
||||||
theme_override_constants/margin_right = 5
|
theme_override_constants/margin_right = 5
|
||||||
|
|
||||||
[node name="HBoxContainer" type="HBoxContainer" parent="Button/MarginContainer"]
|
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="EnclosingSymbolLabel" type="Label" parent="Button/MarginContainer/HBoxContainer"]
|
[node name="EnclosingSymbolLabel" type="Label" parent="MarginContainer/HBoxContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
|
||||||
text = "Containing Symbol Name"
|
text = "Containing Symbol Name"
|
||||||
text_overrun_behavior = 3
|
|
||||||
|
|
||||||
[node name="FileNameLabel" type="Label" parent="Button/MarginContainer/HBoxContainer"]
|
[node name="Spacer" type="Control" parent="MarginContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="FileNameLabel" type="Label" parent="MarginContainer/HBoxContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_colors/font_color = Color(1, 1, 1, 0.7411765)
|
theme_override_colors/font_color = Color(1, 1, 1, 0.7411765)
|
||||||
text = "FileName.cs"
|
text = "FileName.cs"
|
||||||
|
|
||||||
[node name="LineNumberLabel" type="Label" parent="Button/MarginContainer/HBoxContainer"]
|
[node name="LineNumberLabel" type="Label" parent="MarginContainer/HBoxContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_colors/font_color = Color(1, 1, 1, 0.7411765)
|
theme_override_colors/font_color = Color(1, 1, 1, 0.7411765)
|
||||||
|
|||||||
Reference in New Issue
Block a user