From f26755f8aecd434c45d05631ee4d4ee8c2833476 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 20 Jan 2019 17:55:38 +0000 Subject: [PATCH 01/12] Revert "Fix #827 Pester TestName w/expandable str returns nothing (#851)" This reverts commit 161a3ed45fafacfc225d3bc335cd6f5e84a255e5. --- .../Symbols/PesterDocumentSymbolProvider.cs | 25 +++++-------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs b/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs index 762cc002b..729faffc0 100644 --- a/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs +++ b/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs @@ -32,7 +32,8 @@ IEnumerable IDocumentSymbolProvider.ProvideDocumentSymbols( return commandAsts.OfType() .Where(IsPesterCommand) - .Select(ast => ConvertPesterAstToSymbolReference(scriptFile, ast)); + .Select(ast => ConvertPesterAstToSymbolReference(scriptFile, ast)) + .Where(pesterSymbol => pesterSymbol?.TestName != null); } /// @@ -104,21 +105,20 @@ private static PesterSymbolReference ConvertPesterAstToSymbolReference(ScriptFil // Check for an explicit "-Name" parameter if (currentCommandElement is CommandParameterAst parameterAst) { - // Found -Name parameter, move to next element which is the argument for -TestName i++; - - if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName)) + if (parameterAst.ParameterName == "Name" && i < pesterCommandAst.CommandElements.Count) { + testName = alreadySawName ? null : (pesterCommandAst.CommandElements[i] as StringConstantExpressionAst)?.Value; alreadySawName = true; } - continue; } // Otherwise, if an argument is given with no parameter, we assume it's the name // If we've already seen a name, we set the name to null - if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName)) + if (pesterCommandAst.CommandElements[i] is StringConstantExpressionAst testNameStrAst) { + testName = alreadySawName ? null : testNameStrAst.Value; alreadySawName = true; } } @@ -131,19 +131,6 @@ private static PesterSymbolReference ConvertPesterAstToSymbolReference(ScriptFil pesterCommandAst.Extent ); } - - private static bool TryGetTestNameArgument(CommandElementAst commandElementAst, out string testName) - { - testName = null; - - if (commandElementAst is StringConstantExpressionAst testNameStrAst) - { - testName = testNameStrAst.Value; - return true; - } - - return (commandElementAst is ExpandableStringExpressionAst); - } } /// From a0345746cef9af45683d44e3bf9c87f9cb23d5a7 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sun, 20 Jan 2019 18:01:59 +0000 Subject: [PATCH 02/12] Revert "Revert "Fix #827 Pester TestName w/expandable str returns nothing (#851)"" This reverts commit f26755f8aecd434c45d05631ee4d4ee8c2833476. --- .../Symbols/PesterDocumentSymbolProvider.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs b/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs index 729faffc0..762cc002b 100644 --- a/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs +++ b/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs @@ -32,8 +32,7 @@ IEnumerable IDocumentSymbolProvider.ProvideDocumentSymbols( return commandAsts.OfType() .Where(IsPesterCommand) - .Select(ast => ConvertPesterAstToSymbolReference(scriptFile, ast)) - .Where(pesterSymbol => pesterSymbol?.TestName != null); + .Select(ast => ConvertPesterAstToSymbolReference(scriptFile, ast)); } /// @@ -105,20 +104,21 @@ private static PesterSymbolReference ConvertPesterAstToSymbolReference(ScriptFil // Check for an explicit "-Name" parameter if (currentCommandElement is CommandParameterAst parameterAst) { + // Found -Name parameter, move to next element which is the argument for -TestName i++; - if (parameterAst.ParameterName == "Name" && i < pesterCommandAst.CommandElements.Count) + + if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName)) { - testName = alreadySawName ? null : (pesterCommandAst.CommandElements[i] as StringConstantExpressionAst)?.Value; alreadySawName = true; } + continue; } // Otherwise, if an argument is given with no parameter, we assume it's the name // If we've already seen a name, we set the name to null - if (pesterCommandAst.CommandElements[i] is StringConstantExpressionAst testNameStrAst) + if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName)) { - testName = alreadySawName ? null : testNameStrAst.Value; alreadySawName = true; } } @@ -131,6 +131,19 @@ private static PesterSymbolReference ConvertPesterAstToSymbolReference(ScriptFil pesterCommandAst.Extent ); } + + private static bool TryGetTestNameArgument(CommandElementAst commandElementAst, out string testName) + { + testName = null; + + if (commandElementAst is StringConstantExpressionAst testNameStrAst) + { + testName = testNameStrAst.Value; + return true; + } + + return (commandElementAst is ExpandableStringExpressionAst); + } } /// From c978a6f95c4baa53545cbe67700557a4058cb080 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Tue, 22 Jan 2019 20:09:08 +0000 Subject: [PATCH 03/12] send describe block line and info whether pester 4.6.0 is available to extension --- .../CodeLens/PesterCodeLensProvider.cs | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index 619ca0a49..ab937102d 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Management.Automation; using System.Threading; using System.Threading.Tasks; @@ -25,6 +26,12 @@ internal class PesterCodeLensProvider : FeatureProviderBase, ICodeLensProvider /// private IDocumentSymbolProvider _symbolProvider; + /// + /// Pester 4.6.0 introduced a new ScriptblockFilter parameter to be able to run a test based on a line, + /// therefore knowing this information is important. + /// + private bool _pesterV4_6_0_OrHigherAvailable; + /// /// Create a new Pester CodeLens provider for a given editor session. /// @@ -33,6 +40,38 @@ public PesterCodeLensProvider(EditorSession editorSession) { _editorSession = editorSession; _symbolProvider = new PesterDocumentSymbolProvider(); + + DeterminePesterVersion(); + } + + /// + /// Used to determine the value of as a background task. + /// + private void DeterminePesterVersion() + { + Task.Run(() => + { + using (var powerShell = System.Management.Automation.PowerShell.Create()) + { + powerShell.AddCommand("Get-Module") + .AddParameter("ListAvailable") + .AddParameter("Name", "Pester"); + var result = powerShell.Invoke(); + if (result != null && result.Count > 0) + { + foreach (var module in result) + { + if (module.BaseObject is PSModuleInfo psmoduleInfo) + { + if (psmoduleInfo.Version > new Version(4, 6)) + { + _pesterV4_6_0_OrHigherAvailable = true; + } + } + } + } + } + }); } /// @@ -54,7 +93,7 @@ private CodeLens[] GetPesterLens( new ClientCommand( "PowerShell.RunPesterTests", "Run tests", - new object[] { scriptFile.ClientFilePath, false /* No debug */, pesterSymbol.TestName })), + new object[] { scriptFile.ClientFilePath, false /* No debug */, pesterSymbol.TestName, pesterSymbol.ScriptRegion.StartLineNumber, _pesterV4_6_0_OrHigherAvailable })), new CodeLens( this, @@ -63,7 +102,7 @@ private CodeLens[] GetPesterLens( new ClientCommand( "PowerShell.RunPesterTests", "Debug tests", - new object[] { scriptFile.ClientFilePath, true /* Run in debugger */, pesterSymbol.TestName })), + new object[] { scriptFile.ClientFilePath, true /* Run in debugger */, pesterSymbol.TestName, pesterSymbol.ScriptRegion.StartLineNumber, _pesterV4_6_0_OrHigherAvailable })), }; return codeLensResults; From 725f643eb2448763e5e2b8f64d07b49be504f346 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Tue, 22 Jan 2019 22:14:01 +0000 Subject: [PATCH 04/12] send only describeBlockLineNumber as nullable int over the wire to PSES to address PR feedback --- .../CodeLens/PesterCodeLensProvider.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index ab937102d..a18130d08 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -84,6 +84,9 @@ private CodeLens[] GetPesterLens( PesterSymbolReference pesterSymbol, ScriptFile scriptFile) { + // A value of null is a signal to PSES that the available Pester version does not support + // running Describe blocks by name (the test name will used instead then) + int? describeBlockLineNumber = _pesterV4_6_0_OrHigherAvailable ? pesterSymbol.ScriptRegion.StartLineNumber : default(int?); var codeLensResults = new CodeLens[] { new CodeLens( @@ -93,7 +96,7 @@ private CodeLens[] GetPesterLens( new ClientCommand( "PowerShell.RunPesterTests", "Run tests", - new object[] { scriptFile.ClientFilePath, false /* No debug */, pesterSymbol.TestName, pesterSymbol.ScriptRegion.StartLineNumber, _pesterV4_6_0_OrHigherAvailable })), + new object[] { scriptFile.ClientFilePath, false /* No debug */, pesterSymbol.TestName, describeBlockLineNumber })), new CodeLens( this, @@ -102,7 +105,7 @@ private CodeLens[] GetPesterLens( new ClientCommand( "PowerShell.RunPesterTests", "Debug tests", - new object[] { scriptFile.ClientFilePath, true /* Run in debugger */, pesterSymbol.TestName, pesterSymbol.ScriptRegion.StartLineNumber, _pesterV4_6_0_OrHigherAvailable })), + new object[] { scriptFile.ClientFilePath, true /* Run in debugger */, pesterSymbol.TestName, describeBlockLineNumber })), }; return codeLensResults; From 62b101b153d1fa089b7ab40b026ac2f9661cb2ca Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Wed, 23 Jan 2019 00:00:10 +0000 Subject: [PATCH 05/12] use clearer way of passing in null when int is nullable --- .../CodeLens/PesterCodeLensProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index a18130d08..b629abc0a 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -86,7 +86,7 @@ private CodeLens[] GetPesterLens( { // A value of null is a signal to PSES that the available Pester version does not support // running Describe blocks by name (the test name will used instead then) - int? describeBlockLineNumber = _pesterV4_6_0_OrHigherAvailable ? pesterSymbol.ScriptRegion.StartLineNumber : default(int?); + int? describeBlockLineNumber = _pesterV4_6_0_OrHigherAvailable ? (int?)pesterSymbol.ScriptRegion.StartLineNumber : null; var codeLensResults = new CodeLens[] { new CodeLens( From b6b4b4ca42ad9d9c11bd8d094a36f8e63cc4c108 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Thu, 24 Jan 2019 12:49:47 +0000 Subject: [PATCH 06/12] address stylistic nitpicks by Patrick --- .../CodeLens/PesterCodeLensProvider.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index b629abc0a..3e89e7683 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -56,14 +56,14 @@ private void DeterminePesterVersion() powerShell.AddCommand("Get-Module") .AddParameter("ListAvailable") .AddParameter("Name", "Pester"); - var result = powerShell.Invoke(); + ICollection result = powerShell.Invoke(); if (result != null && result.Count > 0) { - foreach (var module in result) + foreach (PSObject module in result) { - if (module.BaseObject is PSModuleInfo psmoduleInfo) + if (module.BaseObject is PSModuleInfo psModuleInfo) { - if (psmoduleInfo.Version > new Version(4, 6)) + if (psModuleInfo.Version > new Version(4, 6)) { _pesterV4_6_0_OrHigherAvailable = true; } From dbd42b583bb1a31dafa32eb9d9c954af0de60aeb Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sat, 26 Jan 2019 15:37:33 +0000 Subject: [PATCH 07/12] Use lazy initialisation to query pester version only when it is needed in GetPesterLens --- .../CodeLens/PesterCodeLensProvider.cs | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index 3e89e7683..9f0755c57 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -7,7 +7,6 @@ using Microsoft.PowerShell.EditorServices.Symbols; using System; using System.Collections.Generic; -using System.Linq; using System.Management.Automation; using System.Threading; using System.Threading.Tasks; @@ -30,7 +29,7 @@ internal class PesterCodeLensProvider : FeatureProviderBase, ICodeLensProvider /// Pester 4.6.0 introduced a new ScriptblockFilter parameter to be able to run a test based on a line, /// therefore knowing this information is important. /// - private bool _pesterV4_6_0_OrHigherAvailable; + private Lazy _pesterV4_6_0_OrHigherAvailable = new Lazy(DeterminePesterVersion); /// /// Create a new Pester CodeLens provider for a given editor session. @@ -40,38 +39,6 @@ public PesterCodeLensProvider(EditorSession editorSession) { _editorSession = editorSession; _symbolProvider = new PesterDocumentSymbolProvider(); - - DeterminePesterVersion(); - } - - /// - /// Used to determine the value of as a background task. - /// - private void DeterminePesterVersion() - { - Task.Run(() => - { - using (var powerShell = System.Management.Automation.PowerShell.Create()) - { - powerShell.AddCommand("Get-Module") - .AddParameter("ListAvailable") - .AddParameter("Name", "Pester"); - ICollection result = powerShell.Invoke(); - if (result != null && result.Count > 0) - { - foreach (PSObject module in result) - { - if (module.BaseObject is PSModuleInfo psModuleInfo) - { - if (psModuleInfo.Version > new Version(4, 6)) - { - _pesterV4_6_0_OrHigherAvailable = true; - } - } - } - } - } - }); } /// @@ -85,8 +52,8 @@ private CodeLens[] GetPesterLens( ScriptFile scriptFile) { // A value of null is a signal to PSES that the available Pester version does not support - // running Describe blocks by name (the test name will used instead then) - int? describeBlockLineNumber = _pesterV4_6_0_OrHigherAvailable ? (int?)pesterSymbol.ScriptRegion.StartLineNumber : null; + // running Describe blocks by name (the test name will used instead then). + int? describeBlockLineNumber = _pesterV4_6_0_OrHigherAvailable.Value ? (int?)pesterSymbol.ScriptRegion.StartLineNumber : null; var codeLensResults = new CodeLens[] { new CodeLens( @@ -111,6 +78,34 @@ private CodeLens[] GetPesterLens( return codeLensResults; } + /// + /// Used to determine the value of as a background task. + /// + private static bool DeterminePesterVersion() + { + using (var powerShell = System.Management.Automation.PowerShell.Create()) + { + powerShell.AddCommand("Get-Module") + .AddParameter("ListAvailable") + .AddParameter("Name", "Pester"); + ICollection result = powerShell.Invoke(); + if (result != null && result.Count > 0) + { + foreach (PSObject module in result) + { + if (module.BaseObject is PSModuleInfo psModuleInfo) + { + if (psModuleInfo.Version > new Version(4, 6)) + { + return true; + } + } + } + } + } + return false; + } + /// /// Get all Pester CodeLenses for a given script file. /// From ba32b20a499adce7200f0aa8f68f040d1dd3fe64 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Tue, 29 Jan 2019 22:20:35 +0000 Subject: [PATCH 08/12] use pscommand instead --- .../CodeLens/PesterCodeLensProvider.cs | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index 9f0755c57..7fb13f404 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -7,6 +7,7 @@ using Microsoft.PowerShell.EditorServices.Symbols; using System; using System.Collections.Generic; +using System.Linq; using System.Management.Automation; using System.Threading; using System.Threading.Tasks; @@ -29,7 +30,7 @@ internal class PesterCodeLensProvider : FeatureProviderBase, ICodeLensProvider /// Pester 4.6.0 introduced a new ScriptblockFilter parameter to be able to run a test based on a line, /// therefore knowing this information is important. /// - private Lazy _pesterV4_6_0_OrHigherAvailable = new Lazy(DeterminePesterVersion); + private Lazy _pesterV4_6_0_OrHigherAvailable; /// /// Create a new Pester CodeLens provider for a given editor session. @@ -39,6 +40,7 @@ public PesterCodeLensProvider(EditorSession editorSession) { _editorSession = editorSession; _symbolProvider = new PesterDocumentSymbolProvider(); + _pesterV4_6_0_OrHigherAvailable = new Lazy(() => DeterminePesterVersion()); } /// @@ -81,24 +83,27 @@ private CodeLens[] GetPesterLens( /// /// Used to determine the value of as a background task. /// - private static bool DeterminePesterVersion() + private bool DeterminePesterVersion() { - using (var powerShell = System.Management.Automation.PowerShell.Create()) + var powerShell = new PSCommand(); + powerShell.AddCommand("Get-Module") + .AddParameter("ListAvailable") + .AddParameter("Name", "Pester"); + + IEnumerable result = Task.Run(() => + { + return _editorSession.PowerShellContext.ExecuteCommandAsync(powerShell); + }).Result; + + if (result != null && result.Any()) { - powerShell.AddCommand("Get-Module") - .AddParameter("ListAvailable") - .AddParameter("Name", "Pester"); - ICollection result = powerShell.Invoke(); - if (result != null && result.Count > 0) + foreach (PSObject module in result) { - foreach (PSObject module in result) + if (module.BaseObject is PSModuleInfo psModuleInfo) { - if (module.BaseObject is PSModuleInfo psModuleInfo) + if (psModuleInfo.Version >= new Version(4, 6)) { - if (psModuleInfo.Version > new Version(4, 6)) - { - return true; - } + return true; } } } From 32c69aaccf7e8127dfada98a230f62f2b6503b12 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Fri, 8 Feb 2019 08:26:26 +0000 Subject: [PATCH 09/12] Update src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs Co-Authored-By: bergmeister --- .../CodeLens/PesterCodeLensProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index 7fb13f404..ebd1dbc97 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -30,7 +30,7 @@ internal class PesterCodeLensProvider : FeatureProviderBase, ICodeLensProvider /// Pester 4.6.0 introduced a new ScriptblockFilter parameter to be able to run a test based on a line, /// therefore knowing this information is important. /// - private Lazy _pesterV4_6_0_OrHigherAvailable; + private readonly Lazy _pesterV4_6_0_OrHigherAvailable; /// /// Create a new Pester CodeLens provider for a given editor session. From e5bddd0a065d00037f89eee839d2f43c87e2b1b3 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sat, 9 Feb 2019 22:33:38 +0000 Subject: [PATCH 10/12] adress style PR comments --- .../CodeLens/PesterCodeLensProvider.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index ebd1dbc97..79787c030 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -85,27 +85,27 @@ private CodeLens[] GetPesterLens( /// private bool DeterminePesterVersion() { - var powerShell = new PSCommand(); - powerShell.AddCommand("Get-Module") - .AddParameter("ListAvailable") - .AddParameter("Name", "Pester"); + var powerShell = new PSCommand() + .AddCommand("Get-Module") + .AddParameter("ListAvailable") + .AddParameter("Name", "Pester"); IEnumerable result = Task.Run(() => { return _editorSession.PowerShellContext.ExecuteCommandAsync(powerShell); }).Result; - if (result != null && result.Any()) + if (result == null) { - foreach (PSObject module in result) + return false; + } + + var minimumPesterVersionSupportingInlineInvocation = new Version(4, 6); + foreach (PSObject module in result) + { + if (module.BaseObject is PSModuleInfo psModuleInfo && psModuleInfo.Version >= minimumPesterVersionSupportingInlineInvocation) { - if (module.BaseObject is PSModuleInfo psModuleInfo) - { - if (psModuleInfo.Version >= new Version(4, 6)) - { - return true; - } - } + return true; } } return false; From 7245bd69493036098f7169b7b01cb1a884e71513 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Wed, 20 Feb 2019 22:12:26 +0000 Subject: [PATCH 11/12] Use Get-Command and make calls to GetPesterCodeLens async/await to the top --- .../CodeLens/CodeLensFeature.cs | 12 +++--- .../CodeLens/PesterCodeLensProvider.cs | 42 ++++++++++--------- .../CodeLens/ReferencesCodeLensProvider.cs | 3 +- .../CodeLenses/ICodeLensProvider.cs | 5 +-- .../CodeLenses/ICodeLenses.cs | 4 +- 5 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs b/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs index e7e2f6910..3f9c11c88 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs @@ -8,8 +8,6 @@ using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol; using Microsoft.PowerShell.EditorServices.Utility; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -99,11 +97,11 @@ private CodeLensFeature( /// /// The PowerShell script file to get CodeLenses for. /// All generated CodeLenses for the given script file. - public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile) + public async Task ProvideCodeLenses(ScriptFile scriptFile) { - return InvokeProviders(provider => provider.ProvideCodeLenses(scriptFile)) - .SelectMany(codeLens => codeLens) - .ToArray(); + var providers = await Task.WhenAll(InvokeProviders(async provider => await provider.ProvideCodeLenses(scriptFile))); + return providers.SelectMany(codeLens => codeLens) + .ToArray(); } /// @@ -118,7 +116,7 @@ private async Task HandleCodeLensRequestAsync( ScriptFile scriptFile = _editorSession.Workspace.GetFile( codeLensParams.TextDocument.Uri); - CodeLens[] codeLensResults = ProvideCodeLenses(scriptFile); + CodeLens[] codeLensResults = await ProvideCodeLenses(scriptFile); var codeLensResponse = new LanguageServer.CodeLens[codeLensResults.Length]; for (int i = 0; i < codeLensResults.Length; i++) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index 79787c030..4149bb6cf 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -30,7 +30,7 @@ internal class PesterCodeLensProvider : FeatureProviderBase, ICodeLensProvider /// Pester 4.6.0 introduced a new ScriptblockFilter parameter to be able to run a test based on a line, /// therefore knowing this information is important. /// - private readonly Lazy _pesterV4_6_0_OrHigherAvailable; + private readonly Lazy> _pesterV4_6_0_OrHigherAvailable; /// /// Create a new Pester CodeLens provider for a given editor session. @@ -40,7 +40,7 @@ public PesterCodeLensProvider(EditorSession editorSession) { _editorSession = editorSession; _symbolProvider = new PesterDocumentSymbolProvider(); - _pesterV4_6_0_OrHigherAvailable = new Lazy(() => DeterminePesterVersion()); + _pesterV4_6_0_OrHigherAvailable = new Lazy>(async () => await DeterminePesterVersion()); } /// @@ -49,13 +49,13 @@ public PesterCodeLensProvider(EditorSession editorSession) /// The Pester symbol to get CodeLenses for. /// The script file the Pester symbol comes from. /// All CodeLenses for the given Pester symbol. - private CodeLens[] GetPesterLens( + private async Task GetPesterLens( PesterSymbolReference pesterSymbol, ScriptFile scriptFile) { // A value of null is a signal to PSES that the available Pester version does not support // running Describe blocks by name (the test name will used instead then). - int? describeBlockLineNumber = _pesterV4_6_0_OrHigherAvailable.Value ? (int?)pesterSymbol.ScriptRegion.StartLineNumber : null; + int? describeBlockLineNumber = await _pesterV4_6_0_OrHigherAvailable.Value ? (int?)pesterSymbol.ScriptRegion.StartLineNumber : null; var codeLensResults = new CodeLens[] { new CodeLens( @@ -83,27 +83,31 @@ private CodeLens[] GetPesterLens( /// /// Used to determine the value of as a background task. /// - private bool DeterminePesterVersion() + private async Task DeterminePesterVersion() { + //if (System.Diagnostics.Debugger.IsAttached) + //{ + // System.Diagnostics.Debugger.Break(); + //} + //else + //{ + // System.Diagnostics.Debugger.Launch(); + //} var powerShell = new PSCommand() - .AddCommand("Get-Module") - .AddParameter("ListAvailable") - .AddParameter("Name", "Pester"); + .AddCommand("Get-Command") + .AddParameter("Name", "Invoke-Pester"); - IEnumerable result = Task.Run(() => - { - return _editorSession.PowerShellContext.ExecuteCommandAsync(powerShell); - }).Result; - - if (result == null) + IEnumerable result = await _editorSession.PowerShellContext.ExecuteCommandAsync(powerShell); + var pesterCommand = result.FirstOrDefault(); + if (pesterCommand == null) { return false; } - var minimumPesterVersionSupportingInlineInvocation = new Version(4, 6); - foreach (PSObject module in result) + if (pesterCommand.BaseObject is FunctionInfo invokePesterFunction) { - if (module.BaseObject is PSModuleInfo psModuleInfo && psModuleInfo.Version >= minimumPesterVersionSupportingInlineInvocation) + var pesterVersion = invokePesterFunction.Version; + if (pesterVersion.Major >= 4 && pesterVersion.Minor >= 6) { return true; } @@ -116,7 +120,7 @@ private bool DeterminePesterVersion() /// /// The script file to get Pester CodeLenses for. /// All Pester CodeLenses for the given script file. - public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile) + public async Task ProvideCodeLenses(ScriptFile scriptFile) { var lenses = new List(); foreach (SymbolReference symbol in _symbolProvider.ProvideDocumentSymbols(scriptFile)) @@ -128,7 +132,7 @@ public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile) continue; } - lenses.AddRange(GetPesterLens(pesterSymbol, scriptFile)); + lenses.AddRange(await GetPesterLens(pesterSymbol, scriptFile)); } } diff --git a/src/PowerShellEditorServices.Host/CodeLens/ReferencesCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/ReferencesCodeLensProvider.cs index 6a5312a93..fa99bca71 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/ReferencesCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/ReferencesCodeLensProvider.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -50,7 +49,7 @@ public ReferencesCodeLensProvider(EditorSession editorSession) /// /// The PowerShell script file to get code lenses for. /// An array of CodeLenses describing all functions in the given script file. - public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile) + public async Task ProvideCodeLenses(ScriptFile scriptFile) { var acc = new List(); foreach (SymbolReference sym in _symbolProvider.ProvideDocumentSymbols(scriptFile)) diff --git a/src/PowerShellEditorServices/CodeLenses/ICodeLensProvider.cs b/src/PowerShellEditorServices/CodeLenses/ICodeLensProvider.cs index 71a1c0243..76245b969 100644 --- a/src/PowerShellEditorServices/CodeLenses/ICodeLensProvider.cs +++ b/src/PowerShellEditorServices/CodeLenses/ICodeLensProvider.cs @@ -3,9 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.PowerShell.EditorServices.Utility; -using System.Collections.Generic; -using System.Management.Automation.Language; using System.Threading; using System.Threading.Tasks; @@ -24,7 +21,7 @@ public interface ICodeLensProvider : IFeatureProvider /// The document for which CodeLenses should be provided. /// /// An array of CodeLenses. - CodeLens[] ProvideCodeLenses(ScriptFile scriptFile); + Task ProvideCodeLenses(ScriptFile scriptFile); /// /// Resolves a CodeLens that was created without a Command. diff --git a/src/PowerShellEditorServices/CodeLenses/ICodeLenses.cs b/src/PowerShellEditorServices/CodeLenses/ICodeLenses.cs index f63319c1c..e69a05fed 100644 --- a/src/PowerShellEditorServices/CodeLenses/ICodeLenses.cs +++ b/src/PowerShellEditorServices/CodeLenses/ICodeLenses.cs @@ -3,8 +3,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; namespace Microsoft.PowerShell.EditorServices.CodeLenses @@ -29,6 +27,6 @@ public interface ICodeLenses /// The document for which CodeLenses should be provided. /// /// An array of CodeLenses. - CodeLens[] ProvideCodeLenses(ScriptFile scriptFile); + Task ProvideCodeLenses(ScriptFile scriptFile); } } From 4ec3b3f19d4727511ca4fb9188be983c6447bbfb Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Wed, 20 Feb 2019 22:50:31 +0000 Subject: [PATCH 12/12] Oops, I did it again... I played with your heart, got lost in the game Oh baby, baby, ... ;-) --- .../CodeLens/PesterCodeLensProvider.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs index 4149bb6cf..83829896e 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -85,14 +85,6 @@ private async Task GetPesterLens( /// private async Task DeterminePesterVersion() { - //if (System.Diagnostics.Debugger.IsAttached) - //{ - // System.Diagnostics.Debugger.Break(); - //} - //else - //{ - // System.Diagnostics.Debugger.Launch(); - //} var powerShell = new PSCommand() .AddCommand("Get-Command") .AddParameter("Name", "Invoke-Pester");