diff --git a/src/PowerShellEditorServices/Analysis/AnalysisService.cs b/src/PowerShellEditorServices/Analysis/AnalysisService.cs index a1ec5a0d4..dd46cbe4f 100644 --- a/src/PowerShellEditorServices/Analysis/AnalysisService.cs +++ b/src/PowerShellEditorServices/Analysis/AnalysisService.cs @@ -3,8 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +using Microsoft.PowerShell.EditorServices.Utility; using Microsoft.Windows.PowerShell.ScriptAnalyzer; using System; +using System.IO; using System.Linq; using System.Management.Automation.Runspaces; using System.Threading; @@ -47,17 +49,30 @@ public class AnalysisService : IDisposable /// public AnalysisService() { - this.analysisRunspace = RunspaceFactory.CreateRunspace(InitialSessionState.CreateDefault2()); - this.analysisRunspace.ApartmentState = ApartmentState.STA; - this.analysisRunspace.ThreadOptions = PSThreadOptions.ReuseThread; - this.analysisRunspace.Open(); + try + { + // Attempt to create a ScriptAnalyzer instance first + // just in case the assembly can't be found and we + // can skip creating an extra runspace. + this.scriptAnalyzer = new ScriptAnalyzer(); + + this.analysisRunspace = RunspaceFactory.CreateRunspace(InitialSessionState.CreateDefault2()); + this.analysisRunspace.ApartmentState = ApartmentState.STA; + this.analysisRunspace.ThreadOptions = PSThreadOptions.ReuseThread; + this.analysisRunspace.Open(); - this.scriptAnalyzer = new ScriptAnalyzer(); - this.scriptAnalyzer.Initialize( - this.analysisRunspace, - new AnalysisOutputWriter(), - null, - IncludedRules); + this.scriptAnalyzer.Initialize( + this.analysisRunspace, + new AnalysisOutputWriter(), + includeRuleNames: IncludedRules, + includeDefaultRules: true); + } + catch (FileNotFoundException) + { + Logger.Write( + LogLevel.Warning, + "Script Analyzer binaries not found, AnalysisService will be disabled."); + } } #endregion @@ -72,7 +87,7 @@ public AnalysisService() /// An array of ScriptFileMarkers containing semantic analysis results. public ScriptFileMarker[] GetSemanticMarkers(ScriptFile file) { - if (file.IsAnalysisEnabled) + if (this.scriptAnalyzer != null && file.IsAnalysisEnabled) { // TODO: This is a temporary fix until we can change how // ScriptAnalyzer invokes their async tasks. diff --git a/test/PowerShellEditorServices.Test.Host/LanguageServerTests.cs b/test/PowerShellEditorServices.Test.Host/LanguageServerTests.cs index a315df418..325f03677 100644 --- a/test/PowerShellEditorServices.Test.Host/LanguageServerTests.cs +++ b/test/PowerShellEditorServices.Test.Host/LanguageServerTests.cs @@ -65,6 +65,22 @@ await this.WaitForEvent( string.IsNullOrEmpty(diagnostics.Diagnostics[0].Message)); } + [Fact] + public async Task ServiceReturnsSemanticMarkers() + { + // Send the 'didOpen' event + await this.SendOpenFileEvent("TestFiles\\SimpleSemanticError.ps1", false); + + // Wait for the diagnostic event + PublishDiagnosticsNotification diagnostics = + await this.WaitForEvent( + PublishDiagnosticsNotification.Type); + + // Was there a semantic error? + Assert.NotEqual(0, diagnostics.Diagnostics.Length); + Assert.Contains("unapproved", diagnostics.Diagnostics[0].Message); + } + [Fact] public async Task ServiceCompletesFunctionName() { diff --git a/test/PowerShellEditorServices.Test.Host/PowerShellEditorServices.Test.Host.csproj b/test/PowerShellEditorServices.Test.Host/PowerShellEditorServices.Test.Host.csproj index e847cc94a..6829c0aa3 100644 --- a/test/PowerShellEditorServices.Test.Host/PowerShellEditorServices.Test.Host.csproj +++ b/test/PowerShellEditorServices.Test.Host/PowerShellEditorServices.Test.Host.csproj @@ -83,6 +83,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/test/PowerShellEditorServices.Test.Host/TestFiles/SimpleSemanticError.ps1 b/test/PowerShellEditorServices.Test.Host/TestFiles/SimpleSemanticError.ps1 new file mode 100644 index 000000000..a4956a97a --- /dev/null +++ b/test/PowerShellEditorServices.Test.Host/TestFiles/SimpleSemanticError.ps1 @@ -0,0 +1,3 @@ +function Do-Work { + # This should trigger the PSUseApprovedVerbs rule +} \ No newline at end of file