diff --git a/sources/tools/Xenko.VisualStudio.Package/NShader/NShaderLanguageService.cs b/sources/tools/Xenko.VisualStudio.Package/NShader/NShaderLanguageService.cs index 09f9842ce3..6ac00c71d2 100644 --- a/sources/tools/Xenko.VisualStudio.Package/NShader/NShaderLanguageService.cs +++ b/sources/tools/Xenko.VisualStudio.Package/NShader/NShaderLanguageService.cs @@ -36,6 +36,7 @@ using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider; using VsShell = Microsoft.VisualStudio.Shell.VsShellUtilities; +using Task = System.Threading.Tasks.Task; using EnvDTE; using Xenko.VisualStudio; @@ -242,7 +243,7 @@ public override Colorizer GetColorizer(IVsTextLines buffer) return base.GetColorizer(buffer); } - public override void OnIdle(bool periodic) + public override async void OnIdle(bool periodic) { var source = GetCurrentNShaderSource(); if (source != null) @@ -263,24 +264,22 @@ public override void OnIdle(bool periodic) var text = source.GetText(); var sourcePath = source.GetFilePath(); + var projectFile = LocateProject(sourcePath); + Trace.WriteLine(string.Format("Parsing Change: {0} Time: {1}", source.ChangeCount, DateTime.Now)); - var thread = new System.Threading.Thread( - () => + try + { + var result = await Task.Run(() => AnalyzeAndGoToDefinition(projectFile, text, new RawSourceSpan(sourcePath, 1, 1))).ConfigureAwait(true); + OutputAnalysisMessages(result, source); + } + catch (Exception ex) + { + lock (errorListProvider) { - try - { - var result = AnalyzeAndGoToDefinition(text, new RawSourceSpan(sourcePath, 1, 1)); - OutputAnalysisMessages(result, source); - } - catch (Exception ex) - { - lock (errorListProvider) - { - errorListProvider.Tasks.Add(new ErrorTask(ex.InnerException ?? ex)); - } - } - }); - thread.Start(); + errorListProvider.Tasks.Add(new ErrorTask(ex.InnerException ?? ex)); + } + } + } } } @@ -288,16 +287,22 @@ public override void OnIdle(bool periodic) base.OnIdle(periodic); } - public RawShaderNavigationResult AnalyzeAndGoToDefinition(string text, RawSourceSpan span) + public string LocateProject(string sourcePath) { // Try to locate containing project var dte = (DTE)GetService(typeof(DTE)); - var projectItem = dte.Solution.FindProjectItem(span.File); + var projectItem = dte.Solution.FindProjectItem(sourcePath); string projectFile = null; if (projectItem != null && projectItem.ContainingProject != null && !string.IsNullOrEmpty(projectItem.ContainingProject.FileName)) { projectFile = projectItem.ContainingProject.FileName; } + + return projectFile; + } + + public RawShaderNavigationResult AnalyzeAndGoToDefinition(string projectFile, string text, RawSourceSpan span) + { return XenkoCommandsProxy.GetProxy()?.AnalyzeAndGoToDefinition(projectFile, text, span) ?? new RawShaderNavigationResult(); } @@ -428,7 +433,7 @@ private static TextSpan ConvertToTextSpan(RawSourceSpan span) private void NavigateToSourceError(object sender, EventArgs e) { - var task = sender as Task; + var task = sender as Microsoft.VisualStudio.Shell.Task; if (task != null) { GoToLocation(new RawSourceSpan(task.Document, task.Line + 1, task.Column + 1), null, false); @@ -516,4 +521,4 @@ public override string Goto(VSConstants.VSStd97CmdID cmd, IVsTextView textView, } } -} \ No newline at end of file +} diff --git a/sources/tools/Xenko.VisualStudio.Package/NShader/NShaderViewFilter.cs b/sources/tools/Xenko.VisualStudio.Package/NShader/NShaderViewFilter.cs index dfd8a15525..d98c9c64c0 100644 --- a/sources/tools/Xenko.VisualStudio.Package/NShader/NShaderViewFilter.cs +++ b/sources/tools/Xenko.VisualStudio.Package/NShader/NShaderViewFilter.cs @@ -90,7 +90,8 @@ private void AnalyzeAndGoToDefinition() Column = column + 1, Line = line + 1 }; - var result = langService.AnalyzeAndGoToDefinition(text, location); + var projectFile = langService.LocateProject(location.File); + var result = langService.AnalyzeAndGoToDefinition(projectFile, text, location); langService.OutputAnalysisAndGotoLocation(result, TextView); } catch (Exception) diff --git a/sources/tools/Xenko.VisualStudio.Package/XenkoPackage.cs b/sources/tools/Xenko.VisualStudio.Package/XenkoPackage.cs index 6b4237ffb4..39819d1d0c 100644 --- a/sources/tools/Xenko.VisualStudio.Package/XenkoPackage.cs +++ b/sources/tools/Xenko.VisualStudio.Package/XenkoPackage.cs @@ -127,16 +127,20 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke dte2 = GetGlobalService(typeof(SDTE)) as DTE2; // Register the C# language service - var serviceContainer = this as IServiceContainer; - errorListProvider = new ErrorListProvider(this) - { - ProviderGuid = new Guid("ad1083c5-32ad-403d-af3d-32fee7abbdf1"), - ProviderName = "Xenko Shading Language" - }; - var langService = new NShaderLanguageService(errorListProvider); - langService.SetSite(this); - langService.InitializeColors(); // Make sure to initialize colors before registering! - serviceContainer.AddService(typeof(NShaderLanguageService), langService, true); + // inspiration & credits: https://github.com/IInspectable/Nav.Language.Extensions/commit/08af3d897afac5a54975660fa03f4b629da405e1#diff-b73c0f368f242625f60cfad9cc11f2d5R88 + AddService(typeof(NShaderLanguageService), async (container, ct, type) => + { + await JoinableTaskFactory.SwitchToMainThreadAsync(ct); + errorListProvider = new ErrorListProvider(this) + { + ProviderGuid = new Guid("ad1083c5-32ad-403d-af3d-32fee7abbdf1"), + ProviderName = "Xenko Shading Language" + }; + var langService = new NShaderLanguageService(errorListProvider); + langService.SetSite(this); + langService.InitializeColors(); // Make sure to initialize colors before registering! + return langService; + }, true); // Add our command handlers for menu (commands must exist in the .vsct file) var mcs = await GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService; @@ -392,7 +396,7 @@ private async System.Threading.Tasks.Task InitializeCommandProxy() { generalOutputPane.OutputStringThreadSafe($"Error Initializing Xenko Language Service: {ex.InnerException ?? ex}\r\n"); generalOutputPane.Activate(); - errorListProvider.Tasks.Add(new ErrorTask(ex.InnerException ?? ex)); + errorListProvider?.Tasks.Add(new ErrorTask(ex.InnerException ?? ex)); } }); thread.Start();