Skip to content

Commit

Permalink
fix: ls doesn't init after extension loads [IDE-617] (#296)
Browse files Browse the repository at this point in the history
* fix: ls doesn't init after extension loads

* fix: delete unused command

* chore: update loading message
  • Loading branch information
ShawkyZ authored Sep 6, 2024
1 parent 94eaa61 commit 83a3778
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 39 deletions.
3 changes: 3 additions & 0 deletions .gitleaksignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
9a05faae741fbfab2a0dbcc3df3452dbb031afef:Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.resx:generic-api-key:126
9a05faae741fbfab2a0dbcc3df3452dbb031afef:Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.resx:generic-api-key:129
9a05faae741fbfab2a0dbcc3df3452dbb031afef:Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.resx:generic-api-key:132
b600b71041ea07c6aae3f1fe451a25680b0db4d7:Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx:generic-api-key:126
b600b71041ea07c6aae3f1fe451a25680b0db4d7:Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx:generic-api-key:129
b600b71041ea07c6aae3f1fe451a25680b0db4d7:Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx:generic-api-key:132
7920b3fa9f77f5461cd7648e6414db7d3e1c766b:snyk-visual-studio-plugin/VSPackage.resx:generic-api-key:130

# file no longer exists
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System.Threading;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Threading;
using Snyk.Common;
using Snyk.Common.Service;
using StreamJsonRpc;

namespace Snyk.VisualStudio.Extension.Language
Expand All @@ -18,5 +19,7 @@ public interface ILanguageClientManager
Task<string> InvokeLogin(CancellationToken cancellationToken);
Task<object> InvokeLogout(CancellationToken cancellationToken);
Task<object> DidChangeConfigurationAsync(CancellationToken cancellationToken);
event AsyncEventHandler<SnykLanguageServerEventArgs> OnLanguageServerReadyAsync;
event AsyncEventHandler<SnykLanguageServerEventArgs> OnLanguageClientNotInitializedAsync;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
{
public static class LanguageClientHelper
{
public static ILanguageClientManager LanguageClientManager()
{
return SnykVSPackage.Instance?.LanguageClientManager;
}

public static bool IsLanguageServerReady()
{
return SnykVSPackage.Instance?.LanguageClientManager != null && SnykVSPackage.Instance.LanguageClientManager.IsReady;
return LanguageClientManager() != null && LanguageClientManager().IsReady;
}
}
}
19 changes: 17 additions & 2 deletions Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ public object GetInitializationOptions()

public event AsyncEventHandler<EventArgs> StartAsync;
public event AsyncEventHandler<EventArgs> StopAsync;
public event AsyncEventHandler<SnykLanguageServerEventArgs> OnLanguageServerReadyAsync;
public event AsyncEventHandler<SnykLanguageServerEventArgs> OnLanguageClientNotInitializedAsync;

public async Task<Connection> ActivateAsync(CancellationToken token)
{
Expand Down Expand Up @@ -157,6 +159,11 @@ public async Task OnLoadedAsync()

public async Task StartServerAsync(bool shouldStart = false)
{
if (StartAsync == null)
{
FireOnLanguageClientNotInitializedAsync();
return;
}
if (!IsReady && StartAsync != null && SnykVSPackage.Instance?.Options != null && shouldStart)
{
if (CustomMessageTarget == null)
Expand All @@ -165,6 +172,8 @@ public async Task StartServerAsync(bool shouldStart = false)
}
Logger.Information("Starting Language Server");
await StartAsync.InvokeAsync(this, EventArgs.Empty);
IsReady = true;
FireOnLanguageServerReadyAsyncEvent();
}
else
{
Expand Down Expand Up @@ -231,7 +240,6 @@ public async Task AttachForCustomMessageAsync(JsonRpc rpc)
Rpc.AllowModificationWhileListening = true;
Rpc.ActivityTracingStrategy = null;
Rpc.AllowModificationWhileListening = false;
IsReady = true;
}

protected void OnStopping() { }
Expand Down Expand Up @@ -354,7 +362,14 @@ public async Task RestartServerAsync()
await RestartAsync(true);
}

// TODO: Add Logging
public void FireOnLanguageServerReadyAsyncEvent()
{
this.OnLanguageServerReadyAsync?.InvokeAsync(this, new SnykLanguageServerEventArgs{IsReady = true}).FireAndForget();
}
public void FireOnLanguageClientNotInitializedAsync()
{
this.OnLanguageClientNotInitializedAsync?.InvokeAsync(this, new SnykLanguageServerEventArgs { IsReady = false }).FireAndForget();
}

private async Task<T> InvokeAsync<T>(string request, CancellationToken t)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public async Task OnHasAuthenticated(JToken arg)

if (serviceProvider.Options.AutoScan)
{
await this.languageClientManager.InvokeWorkspaceScanAsync(CancellationToken.None);
await this.languageClientManager.InvokeWorkspaceScanAsync(SnykVSPackage.Instance.DisposalToken);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;

namespace Snyk.VisualStudio.Extension.Language
{
public class SnykLanguageServerEventArgs : EventArgs
{
public bool IsReady { get; set; }
}
}
4 changes: 4 additions & 0 deletions Snyk.VisualStudio.Extension.2022/Resources/SnykLsInit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*
Snyk Security is loading...
Please hold on for a moment.
*/
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,8 @@ public bool Authenticate()
Logger.Information("Api token is invalid. Attempting to authenticate via snyk auth");
ThreadHelper.JoinableTaskFactory.Run(async ()=>
{
await ServiceProvider.Package.LanguageClientManager.InvokeLogout(CancellationToken.None);
var token = await ServiceProvider.Package.LanguageClientManager.InvokeLogin(CancellationToken.None);
await ServiceProvider.Package.LanguageClientManager.InvokeLogout(SnykVSPackage.Instance.DisposalToken);
var token = await ServiceProvider.Package.LanguageClientManager.InvokeLogin(SnykVSPackage.Instance.DisposalToken);
ApiToken = CreateAuthenticationToken(token);
});
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private void OptionsDialogPageOnSettingsChanged(object sender, SnykSettingsChang
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
this.UpdateViewFromOptionsDialog();
if (LanguageClientHelper.IsLanguageServerReady())
await ServiceProvider.Package.LanguageClientManager.DidChangeConfigurationAsync(CancellationToken.None);
await ServiceProvider.Package.LanguageClientManager.DidChangeConfigurationAsync(SnykVSPackage.Instance.DisposalToken);
}).FireAndForget();

public async Task OnAuthenticationSuccessfulAsync(string apiToken)
Expand Down Expand Up @@ -356,7 +356,7 @@ private void StartSastEnablementCheckLoop()
try
{
if (!LanguageClientHelper.IsLanguageServerReady()) return;
var sastSettings = await this.ServiceProvider.Package.LanguageClientManager.InvokeGetSastEnabled(CancellationToken.None);
var sastSettings = await this.ServiceProvider.Package.LanguageClientManager.InvokeGetSastEnabled(SnykVSPackage.Instance.DisposalToken);
bool snykCodeEnabled = sastSettings != null ? sastSettings.SnykCodeEnabled : false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
<Compile Include="Commands\SnykOpenSettingsCommand.cs" />
<Compile Include="Commands\SnykScanCommand.cs" />
<Compile Include="Commands\SnykStopCurrentTaskCommand.cs" />
<Compile Include="Language\SnykLanguageServerEventArgs.cs" />
<Compile Include="ManualAssemblyResolver.cs" />
<Compile Include="Microsoft\HtmlParser\CssStylesheet.cs" />
<Compile Include="Microsoft\HtmlParser\HtmlCssParser.cs" />
Expand All @@ -101,6 +102,10 @@
<Compile Include="Model\Severity.cs" />
<Compile Include="Product.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="Resources\SnykLsInit.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<IncludeInVSIX>true</IncludeInVSIX>
</Content>
<Compile Include="Service\Domain\FeaturesSettings.cs" />
<Compile Include="Service\ISnykProgressWorker.cs" />
<Compile Include="Service\ISnykService.cs" />
Expand Down
45 changes: 39 additions & 6 deletions Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using Snyk.Common.Settings;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using EnvDTE;
using Microsoft;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell;
Expand All @@ -18,6 +21,7 @@
using Snyk.VisualStudio.Extension.UI.Notifications;
using Snyk.VisualStudio.Extension.UI.Toolwindow;
using Task = System.Threading.Tasks.Task;
using Thread = EnvDTE.Thread;

namespace Snyk.VisualStudio.Extension
{
Expand Down Expand Up @@ -196,8 +200,10 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke

await InitializeGeneralOptionsAsync();

// Initialize analytics
var vsVersion = await GetReadableVsVersionAsync();

// Initialize LS
Logger.Information("Initializing Language Server");
await InitializeLanguageClientAsync();

// Initialize commands
Logger.Information("Initialize Commands()");
Expand All @@ -214,8 +220,6 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke
ToolWindowControl.InitializeEventListeners(this.serviceProvider);
ToolWindowControl.Initialize(this.serviceProvider);

await InitializeLanguageClientAsync();

// Notify package has been initialized
IsInitialized = true;
initializationTaskCompletionSource.SetResult(true);
Expand Down Expand Up @@ -245,9 +249,11 @@ private async Task InitializeLanguageClientAsync()
var componentModel = GetGlobalService(typeof(SComponentModel)) as IComponentModel;
Assumes.Present(componentModel);
var languageServerClientManager = componentModel.GetService<ILanguageClientManager>();
if(languageServerClientManager != null && !languageServerClientManager.IsReady)
LanguageClientManager = languageServerClientManager;
LanguageClientManager.OnLanguageClientNotInitializedAsync += LanguageClientManagerOnOnLanguageClientNotInitializedAsync;
LanguageClientManager.OnLanguageServerReadyAsync += LanguageClientManagerOnOnLanguageServerReadyAsync;
if (languageServerClientManager != null && !languageServerClientManager.IsReady)
{
LanguageClientManager = languageServerClientManager;
// If CLI download is necessary, Skip initializing.
if (this.serviceProvider.TasksService.ShouldDownloadCli())
{
Expand All @@ -262,6 +268,33 @@ private async Task InitializeLanguageClientAsync()
}
}

private async Task LanguageClientManagerOnOnLanguageServerReadyAsync(object sender, SnykLanguageServerEventArgs args)
{
// Sleep for three seconds before closing the temp window
await Task.Delay(3000);
await JoinableTaskFactory.SwitchToMainThreadAsync();
tempOpenedFileWindow?.Close(vsSaveChanges.vsSaveChangesNo);
}

private Window tempOpenedFileWindow;
private async Task LanguageClientManagerOnOnLanguageClientNotInitializedAsync(object sender, SnykLanguageServerEventArgs args)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();

var dte = (DTE)await GetServiceAsync(typeof(DTE));
if (dte == null)
{
return;
}

// Get the path to the file within the installed extension directory
var assemblyLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var filePath = Path.Combine(assemblyLocation, "Resources", "SnykLsInit.cs");

// Open the file
tempOpenedFileWindow = dte.ItemOperations.OpenFile(filePath, EnvDTE.Constants.vsViewKindTextView);
}

private async Task InitializeGeneralOptionsAsync()
{
if (GeneralOptionsDialogPage == null)
Expand Down
43 changes: 22 additions & 21 deletions Snyk.VisualStudio.Extension.2022/UI/Toolwindow/MessagePanel.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Community.VisualStudio.Toolkit;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Threading;
using Serilog;
using Serilog.Core;
using Snyk.Common;
using Snyk.VisualStudio.Extension.Language;
using Snyk.VisualStudio.Extension.Service;

namespace Snyk.VisualStudio.Extension.UI.Toolwindow
Expand All @@ -23,16 +20,6 @@ namespace Snyk.VisualStudio.Extension.UI.Toolwindow
/// </summary>
public partial class MessagePanel : UserControl
{


//[ComVisible(true)]
//public class ScriptManager
//{
// public void OpenFileInEditor(string filePath, int lineNumber, int columnNumber)
// {
// // DTE stuff
// }
//}
private static readonly ILogger Logger = LogManager.ForContext<MessagePanel>();
private readonly IList<StackPanel> panels;

Expand All @@ -42,11 +29,6 @@ public partial class MessagePanel : UserControl
public MessagePanel()
{
this.InitializeComponent();
//Testbrowser.ObjectForScripting = new ScriptManager();
//Testbrowser.ContextMenu.IsEnabled = false;
//Testbrowser.= true;
// To Execute from Javascript window.external.OpenFileInEditor(filePath, int lineNumber, int columnNumber)
//Testbrowser.DataContext = "<html></html>";

this.panels = new List<StackPanel>
{
Expand All @@ -58,6 +40,17 @@ public MessagePanel()
this.scanningProjectMessagePanel,
};
snykDogLogo.Source = SnykIconProvider.GetImageSourceFromPath(SnykIconProvider.SnykDogLogoIconPath);
var languageClientManager = LanguageClientHelper.LanguageClientManager();
if (languageClientManager != null)
{
languageClientManager.OnLanguageServerReadyAsync += LanguageClientManagerOnOnLanguageServerReady;
}
}

private async Task LanguageClientManagerOnOnLanguageServerReady(object sender, SnykLanguageServerEventArgs e)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
testCodeNowButton.IsEnabled = true;
}

/// <summary>
Expand Down Expand Up @@ -101,7 +94,15 @@ public string Text
/// <summary>
/// Show overview screen message.
/// </summary>
public void ShowOverviewScreenMessage() => this.ShowPanel(this.overviewPanel);
public void ShowOverviewScreenMessage()
{
if (!LanguageClientHelper.IsLanguageServerReady())
{
testCodeNowButton.IsEnabled = false;
}

this.ShowPanel(this.overviewPanel);
}

private void RunButton_Click(object sender, RoutedEventArgs e) => ThreadHelper.JoinableTaskFactory.RunAsync(SnykTasksService.Instance.ScanAsync);

Expand All @@ -120,7 +121,7 @@ private void TestCodeNow_Click(object sender, RoutedEventArgs e)
ThreadHelper.JoinableTaskFactory.Run(RunTestCodeNowAsync);
}

private async System.Threading.Tasks.Task RunTestCodeNowAsync()
private async Task RunTestCodeNowAsync()
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
this.testCodeNowButton.IsEnabled = false; // Disable the button while authenticating
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ private void UpdateTreeNodeItemsState() => ThreadHelper.JoinableTaskFactory.Run(
SastSettings sastSettings = null;
if (LanguageClientHelper.IsLanguageServerReady())
{
sastSettings = await this.serviceProvider.Package.LanguageClientManager.InvokeGetSastEnabled(CancellationToken.None);
sastSettings = await this.serviceProvider.Package.LanguageClientManager.InvokeGetSastEnabled(SnykVSPackage.Instance.DisposalToken);
}
this.resultsTree.CodeQualityRootNode.State = this.GetSnykCodeRootNodeState(sastSettings, options.SnykCodeQualityEnabled);
Expand Down Expand Up @@ -695,7 +695,7 @@ private void ShowWelcomeOrRunScanScreen()
{
var options = this.serviceProvider.Options;

if (options.ApiToken.IsValid())
if (options.ApiToken.IsValid() && LanguageClientHelper.IsLanguageServerReady())
{
this.context.TransitionTo(RunScanState.Instance);
return;
Expand Down

0 comments on commit 83a3778

Please sign in to comment.