diff --git a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs index 43ca4b91d..c6cbf3eef 100644 --- a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs +++ b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs @@ -1091,7 +1091,7 @@ protected async Task HandleCommentHelpRequest( { // todo create a semantic marker api that take only string var analysisResults = await EditorSession.AnalysisService.GetSemanticMarkersAsync( - scriptFile, + functionDefinitionAst.Extent.Text, AnalysisService.GetCommentHelpRuleSettings( true, false, @@ -1099,14 +1099,15 @@ protected async Task HandleCommentHelpRequest( true, "before")); - var analysisResult = analysisResults?.FirstOrDefault(x => - { - return x.Correction != null - && x.Correction.Edits[0].StartLineNumber == expectedFunctionLine; - }); - // find the analysis result whose correction starts on - result.Content = analysisResult?.Correction.Edits[0].Text.Split('\n').Select(x => x.Trim('\r')).ToArray(); + result.Content = analysisResults? + .FirstOrDefault()? + .Correction? + .Edits[0] + .Text + .Split('\n') + .Select(x => x.Trim('\r')) + .ToArray(); } await requestContext.SendResult(result); diff --git a/src/PowerShellEditorServices/Analysis/AnalysisService.cs b/src/PowerShellEditorServices/Analysis/AnalysisService.cs index f5987d888..68ddd050c 100644 --- a/src/PowerShellEditorServices/Analysis/AnalysisService.cs +++ b/src/PowerShellEditorServices/Analysis/AnalysisService.cs @@ -197,7 +197,7 @@ public static Hashtable GetPSSASettingsHashtable(IDictionary /// An array of ScriptFileMarkers containing semantic analysis results. public async Task GetSemanticMarkersAsync(ScriptFile file) { - return await GetSemanticMarkersAsync(file, activeRules, settingsPath); + return await GetSemanticMarkersAsync(file, activeRules, settingsPath); } /// @@ -211,6 +211,19 @@ public async Task GetSemanticMarkersAsync(ScriptFile file, H return await GetSemanticMarkersAsync(file, null, settings); } + /// + /// Perform semantic analysis on the given script with the given settings. + /// + /// The script content to be analyzed. + /// ScriptAnalyzer settings + /// + public async Task GetSemanticMarkersAsync( + string scriptContent, + Hashtable settings) + { + return await GetSemanticMarkersAsync(scriptContent, null, settings); + } + /// /// Returns a list of builtin-in PSScriptAnalyzer rules /// @@ -252,11 +265,29 @@ private async Task GetSemanticMarkersAsync( TSettings settings) where TSettings : class { if (hasScriptAnalyzerModule - && file.IsAnalysisEnabled - && (typeof(TSettings) == typeof(string) || typeof(TSettings) == typeof(Hashtable)) + && file.IsAnalysisEnabled) + { + return await GetSemanticMarkersAsync( + file.Contents, + rules, + settings); + } + else + { + // Return an empty marker list + return new ScriptFileMarker[0]; + } + } + + private async Task GetSemanticMarkersAsync( + string scriptContent, + string[] rules, + TSettings settings) where TSettings : class + { + if ((typeof(TSettings) == typeof(string) || typeof(TSettings) == typeof(Hashtable)) && (rules != null || settings != null)) { - var scriptFileMarkers = await GetDiagnosticRecordsAsync(file, rules, settings); + var scriptFileMarkers = await GetDiagnosticRecordsAsync(scriptContent, rules, settings); return scriptFileMarkers.Select(ScriptFileMarker.FromDiagnosticRecord).ToArray(); } else @@ -318,9 +349,9 @@ private void EnumeratePSScriptAnalyzerRules() } private async Task GetDiagnosticRecordsAsync( - ScriptFile file, - string[] rules, - TSettings settings) where TSettings : class + string scriptContent, + string[] rules, + TSettings settings) where TSettings : class { var diagnosticRecords = new PSObject[0]; @@ -346,7 +377,7 @@ private async Task GetDiagnosticRecordsAsync( "Invoke-ScriptAnalyzer", new Dictionary { - { "ScriptDefinition", file.Contents }, + { "ScriptDefinition", scriptContent }, { settingParameter, settingArgument } }); } @@ -358,6 +389,7 @@ private async Task GetDiagnosticRecordsAsync( return diagnosticRecords; } + private PSObject[] InvokePowerShell(string command, IDictionary paramArgMap) { using (var powerShell = System.Management.Automation.PowerShell.Create()) @@ -389,7 +421,8 @@ private PSObject[] InvokePowerShell(string command, IDictionary private async Task InvokePowerShellAsync(string command, IDictionary paramArgMap) { - var task = Task.Run(() => { + var task = Task.Run(() => + { return InvokePowerShell(command, paramArgMap); });