Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Intellisense displays only the elements related to the current context #386

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
34a695b
feat: Add test Intellisense type affinity
workgroupengineering Sep 5, 2023
6f25178
feat: Intellisense displays only the elements related to the current …
workgroupengineering Sep 5, 2023
979ef4b
feat: ItemTypeAttribute
workgroupengineering Oct 2, 2023
25517d2
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Oct 10, 2023
3dbe225
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Oct 17, 2023
d5d5b67
Merge branch 'master' into features/Intellisense/Type-Affinity
prashantvc Oct 18, 2023
829b945
Merge branch 'features/Intellisense/Type-Affinity' of https://github.…
workgroupengineering Oct 18, 2023
67f5970
feat: Add Cache to Wrapper Types
workgroupengineering Oct 18, 2023
0cbadd2
fix: Avoid filter when itemType is `System.Object"`
workgroupengineering Oct 19, 2023
846f5b7
feat: Add test to check xmlns
workgroupengineering Oct 19, 2023
d523046
fix: element with xmlns
workgroupengineering Oct 19, 2023
a7743c5
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Oct 19, 2023
fc7b8ef
fix: Conflict with master
workgroupengineering Oct 31, 2023
cc1a8e6
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Nov 3, 2023
6d250f3
fix: NRE
workgroupengineering Nov 3, 2023
8de6ad7
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Nov 9, 2023
10be223
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Nov 10, 2023
e9c5e3e
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Nov 15, 2023
404dc84
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Nov 28, 2023
c0ad7a5
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Nov 30, 2023
fc33a06
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Dec 11, 2023
25d2454
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Jan 30, 2024
26bbbb4
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Mar 28, 2024
9ad5cda
fix: Erly dispose
workgroupengineering Mar 28, 2024
a7aedcb
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Apr 4, 2024
7c5e7d1
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering Apr 6, 2024
3a8d6f4
fix: memory leak
workgroupengineering Apr 16, 2024
d9b8c67
fix: Dispose
workgroupengineering Apr 18, 2024
275de74
Merge branch 'master' into features/Intellisense/Type-Affinity
workgroupengineering May 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,18 @@ internal class MissingAliasSuggestedAction : BaseSuggestedAction, ISuggestedActi
private readonly ITextBufferFactoryService _bufferFactory;
private readonly ITextViewRoleSet _previewRoleSet;

public MissingAliasSuggestedAction(ITrackingSpan span, IWpfDifferenceViewerFactoryService diffFactory, IDifferenceBufferFactoryService diffBufferFactory, ITextBufferFactoryService bufferFactory, ITextEditorFactoryService textEditorFactoryService, IReadOnlyDictionary<string, string> inverseNamespaces)
public MissingAliasSuggestedAction(ITrackingSpan span,
IWpfDifferenceViewerFactoryService diffFactory,
IDifferenceBufferFactoryService diffBufferFactory,
ITextBufferFactoryService bufferFactory,
ITextEditorFactoryService textEditorFactoryService,
IReadOnlyDictionary<string, ISet<string>> inverseNamespaces)
{
_span = span;
_snapshot = _span.TextBuffer.CurrentSnapshot;
_targetClassName = _span.GetText(_snapshot);
var targetClassMetadata = inverseNamespaces.FirstOrDefault(x => x.Key.Split('.').Last() == _targetClassName);
_namespaceAlias = targetClassMetadata.Value.Split(':').Last().Split('.').Last();
_namespaceAlias = targetClassMetadata.Value.First().Split(':').Last().Split('.').Last();
_diffFactory = diffFactory;
_diffBufferFactory = diffBufferFactory;
_bufferFactory = bufferFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,21 @@ internal class MissingNamespaceAndAliasSuggestedAction : BaseSuggestedAction, IS
private readonly Dictionary<string, string> _aliases;
private readonly ITextViewRoleSet _previewRoleSet;

public MissingNamespaceAndAliasSuggestedAction(ITrackingSpan span, IWpfDifferenceViewerFactoryService diffFactory,
IDifferenceBufferFactoryService diffBufferFactory, ITextBufferFactoryService bufferFactory, ITextEditorFactoryService textEditorFactoryService,
IReadOnlyDictionary<string, string> inverseNamespaces, Dictionary<string, string> aliases)
public MissingNamespaceAndAliasSuggestedAction(ITrackingSpan span,
IWpfDifferenceViewerFactoryService diffFactory,
IDifferenceBufferFactoryService diffBufferFactory,
ITextBufferFactoryService bufferFactory,
ITextEditorFactoryService textEditorFactoryService,
IReadOnlyDictionary<string, ISet<string>> inverseNamespaces,
Dictionary<string, string> aliases)
{
_span = span;
_snapshot = _span.TextBuffer.CurrentSnapshot;
_targetClassName = _span.GetText(_snapshot);
_targetClassMetadata = inverseNamespaces.FirstOrDefault(x => x.Key.Split('.').Last() == _targetClassName);
_targetClassMetadata = inverseNamespaces
.Where(x => x.Key.Split('.').Last() == _targetClassName)
.Select(x => new KeyValuePair<string, string>(x.Key, x.Value.First()))
.FirstOrDefault();

// _targetClassMetadata.Value is the namespace of the control we are trying to add the namespace to.
// It is usually in the format using:MyNamespace.Something.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using AvaloniaVS.Shared.SuggestedActions.Actions.Base;
using AvaloniaVS.Shared.SuggestedActions.Helpers;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Differencing;
using Microsoft.VisualStudio.Text.Editor;
Expand All @@ -22,12 +23,20 @@ internal class MissingNamespaceSuggestedAction : BaseSuggestedAction, ISuggested
private readonly string _alias;
private readonly ITextViewRoleSet _previewRoleSet;

public MissingNamespaceSuggestedAction(ITrackingSpan span, IWpfDifferenceViewerFactoryService diffFactory, IDifferenceBufferFactoryService diffBufferFactory,
ITextBufferFactoryService bufferFactory, ITextEditorFactoryService textEditorFactoryService, IReadOnlyDictionary<string, string> inverseNamespaces,
public MissingNamespaceSuggestedAction(ITrackingSpan span,
IWpfDifferenceViewerFactoryService diffFactory,
IDifferenceBufferFactoryService diffBufferFactory,
ITextBufferFactoryService bufferFactory,
ITextEditorFactoryService textEditorFactoryService,
IReadOnlyDictionary<string, ISet<string>> inverseNamespaces,
Dictionary<string, string> aliases, string alias)
{
_span = span;
_targetClassMetadata = inverseNamespaces.FirstOrDefault(x => x.Key.Split('.').Last() == _span.GetText(_span.TextBuffer.CurrentSnapshot));
_targetClassMetadata = inverseNamespaces
.Where(x => x.Key.Split('.').Last() == _span.GetText(_span.TextBuffer.CurrentSnapshot))
.Select(x => new KeyValuePair<string, string>(x.Key, x.Value.First()))
.FirstOrDefault();

DisplayText = $"Add xmlns {alias}";
_diffFactory = diffFactory;
_diffBufferFactory = diffBufferFactory;
Expand Down
44 changes: 34 additions & 10 deletions AvaloniaVS.Shared/SuggestedActions/SuggestedActionsSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ class SuggestedActionsSource : ISuggestedActionsSource
private readonly ITextEditorFactoryService _textEditorFactoryService;
private readonly ITextView _textView;

public SuggestedActionsSource(SuggestedActionsSourceProvider testSuggestedActionsSourceProvider, ITextView textView, ITextBuffer textBuffer,
IWpfDifferenceViewerFactoryService diffFactory, IDifferenceBufferFactoryService diffBufferFactory, ITextBufferFactoryService bufferFactory,
public SuggestedActionsSource(SuggestedActionsSourceProvider testSuggestedActionsSourceProvider,
ITextView textView,
ITextBuffer textBuffer,
IWpfDifferenceViewerFactoryService diffFactory,
IDifferenceBufferFactoryService diffBufferFactory,
ITextBufferFactoryService bufferFactory,
ITextEditorFactoryService textEditorFactoryService)
{
_factory = testSuggestedActionsSourceProvider;
Expand Down Expand Up @@ -56,19 +60,34 @@ public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCateg
ISuggestedAction suggestedAction = null;
if (availableSuggestedActions.Item1)
{
suggestedAction = new MissingNamespaceAndAliasSuggestedAction(trackingSpan, _diffFactory, _diffBufferFactory, _bufferFactory, _textEditorFactoryService,
metadata.CompletionMetadata.InverseNamespace, CompletionEngine.GetNamespaceAliases(extent.Span.Snapshot.TextBuffer.CurrentSnapshot.GetText()));
suggestedAction = new MissingNamespaceAndAliasSuggestedAction(trackingSpan,
_diffFactory,
_diffBufferFactory,
_bufferFactory,
_textEditorFactoryService,
metadata.CompletionMetadata.InverseNamespace,
CompletionEngine.GetNamespaceAliases(extent.Span.Snapshot.TextBuffer.CurrentSnapshot.GetText()));
}
else if (availableSuggestedActions.Item2)
{
suggestedAction = new MissingAliasSuggestedAction(trackingSpan, _diffFactory, _diffBufferFactory, _bufferFactory, _textEditorFactoryService,
metadata.CompletionMetadata.InverseNamespace);
suggestedAction = new MissingAliasSuggestedAction(trackingSpan,
_diffFactory,
_diffBufferFactory,
_bufferFactory,
_textEditorFactoryService,
metadata.CompletionMetadata.InverseNamespace);
}
else if (availableSuggestedActions.Item3)
{
HasAlias(out var alias);
suggestedAction = new MissingNamespaceSuggestedAction(trackingSpan, _diffFactory, _diffBufferFactory, _bufferFactory, _textEditorFactoryService,
metadata.CompletionMetadata.InverseNamespace, CompletionEngine.GetNamespaceAliases(extent.Span.Snapshot.TextBuffer.CurrentSnapshot.GetText()), alias);
suggestedAction = new MissingNamespaceSuggestedAction(trackingSpan,
_diffFactory,
_diffBufferFactory,
_bufferFactory,
_textEditorFactoryService,
metadata.CompletionMetadata.InverseNamespace,
CompletionEngine.GetNamespaceAliases(extent.Span.Snapshot.TextBuffer.CurrentSnapshot.GetText())
, alias);
}
return new SuggestedActionSet[] { new SuggestedActionSet(new ISuggestedAction[] { suggestedAction }) };
}
Expand Down Expand Up @@ -131,10 +150,15 @@ private bool TryGetWordUnderCaret(out TextExtent wordExtent)
{
return (false, false, false);
}
var targetClassMetadata = metadata.CompletionMetadata.InverseNamespace.FirstOrDefault(x => x.Key.Split('.').Last() == targetClassName);
var targetClassMetadata = metadata.CompletionMetadata
.InverseNamespace
.Where(x => x.Key.Split('.').Last() == targetClassName)
.Select(x => new { x.Key, Value = x.Value.FirstOrDefault() })
.FirstOrDefault();

// Exclude all classes from avaloniaui namespace because controls from this namespace are included by default.
if (targetClassMetadata.Value != null && targetClassMetadata.Key != null && !metadata.CompletionMetadata.Namespaces.First(x => x.Key == "https://github.com/avaloniaui").Value.ContainsKey(targetClassName))
if (targetClassMetadata is not null && targetClassMetadata.Value != null && targetClassMetadata.Key != null
&& !metadata.CompletionMetadata.Namespaces.First(x => x.Key == "https://github.com/avaloniaui").Value.ContainsKey(targetClassName))
{
if (!CompletionEngine.GetNamespaceAliases(span.TextBuffer.CurrentSnapshot.GetText()).ContainsValue(targetClassMetadata.Value))
{
Expand Down
30 changes: 14 additions & 16 deletions AvaloniaVS.Shared/Views/AvaloniaDesigner.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using Serilog;
using Task = System.Threading.Tasks.Task;


namespace AvaloniaVS.Views
{
public enum AvaloniaDesignerView
Expand Down Expand Up @@ -443,7 +444,7 @@ public bool TryProcessZoomLevelValue(out double scaling)
Dispatcher.BeginInvoke(() =>
ZoomLevel = string.Format(CultureInfo.InvariantCulture, "{0}%", Math.Round(Math.Min(x, y), 2, MidpointRounding.ToEven) * 100),
System.Windows.Threading.DispatcherPriority.Background);

}
else
{
Expand Down Expand Up @@ -559,7 +560,8 @@ private void RebuildMetadata(string assemblyPath)
string intermediateOutputPath = GetIntermediateOutputPath(storage);
if (metadata.CompletionMetadata == null || metadata.NeedInvalidation)
{
CreateCompletionMetadataAsync(intermediateOutputPath, assemblyPath, metadata).FireAndForget();
CreateCompletionMetadataAsync(intermediateOutputPath, assemblyPath, metadata)
.FireAndForget();
}
}
}
Expand All @@ -572,48 +574,44 @@ private static async Task CreateCompletionMetadataAsync(
string xamlAssemblyPath,
XamlBufferMetadata target)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var sw = new Stopwatch();
sw.Start();
Log.Logger.Information("Started AvaloniaDesigner.CreateCompletionMetadataAsync() for {ExecutablePath}", intermediateOutputPath);

if (_metadataCache == null)
{
_metadataCache = new Dictionary<string, Task<Metadata>>();
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var dte = (DTE)Package.GetGlobalService(typeof(DTE));

dte.Events.BuildEvents.OnBuildBegin += (s, e) => _metadataCache.Clear();
}

Log.Logger.Information("Started AvaloniaDesigner.CreateCompletionMetadataAsync() for {ExecutablePath}", intermediateOutputPath);

try
{
var sw = Stopwatch.StartNew();
await TaskScheduler.Default;

Task<Metadata> metadataLoad;

if (!_metadataCache.TryGetValue(intermediateOutputPath, out metadataLoad))
{
metadataLoad = Task.Run(() =>
{
return _metadataReader.GetForTargetAssembly(new AvaloniaCompilationAssemblyProvider(intermediateOutputPath, xamlAssemblyPath));
});
metadataLoad?.Dispose();
metadataLoad = Task.Run(() => _metadataReader.GetForTargetAssembly(new AvaloniaCompilationAssemblyProvider(intermediateOutputPath, xamlAssemblyPath)));
_metadataCache[intermediateOutputPath] = metadataLoad;
}
target.CompletionMetadata?.Dispose();

target.CompletionMetadata = await metadataLoad;

target.NeedInvalidation = false;

sw.Stop();

Log.Logger.Verbose("Finished AvaloniaDesigner.CreateCompletionMetadataAsync() took {Time} for {ExecutablePath}", sw.Elapsed, intermediateOutputPath);
}
catch (Exception ex)
{
Log.Logger.Error(ex, "Error creating XAML completion metadata");
}
finally
{
Log.Logger.Verbose("Finished AvaloniaDesigner.CreateCompletionMetadataAsync()");
sw?.Stop();
Log.Logger.Verbose("Finished AvaloniaDesigner.CreateCompletionMetadataAsync() {0}", sw?.Elapsed);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<AssemblyOriginatorKeyFile>$(SolutionDir)Key.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="dnlib" Version="3.6.0" />
<PackageReference Include="dnlib" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.Ide.CompletionEngine\Avalonia.Ide.CompletionEngine.csproj" />
Expand Down
Loading