From 5ac8362b32cf4843d3313c8b8253ddb609dd10d7 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Thu, 23 Aug 2018 16:44:21 -0700 Subject: [PATCH 1/4] [Style] Refactor FindReferencesOfSymbol code --- .../Language/LanguageService.cs | 116 +++++++++--------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/src/PowerShellEditorServices/Language/LanguageService.cs b/src/PowerShellEditorServices/Language/LanguageService.cs index 5dfad5aa4..d46faac2b 100644 --- a/src/PowerShellEditorServices/Language/LanguageService.cs +++ b/src/PowerShellEditorServices/Language/LanguageService.cs @@ -294,72 +294,76 @@ public async Task FindReferencesOfSymbol( ScriptFile[] referencedFiles, Workspace workspace) { - if (foundSymbol != null) + if (foundSymbol == null) { - int symbolOffset = referencedFiles[0].GetOffsetAtPosition( - foundSymbol.ScriptRegion.StartLineNumber, - foundSymbol.ScriptRegion.StartColumnNumber); + return null; + } - // Make sure aliases have been loaded - await GetAliases(); + int symbolOffset = referencedFiles[0].GetOffsetAtPosition( + foundSymbol.ScriptRegion.StartLineNumber, + foundSymbol.ScriptRegion.StartColumnNumber); - // We want to look for references first in referenced files, hence we use ordered dictionary - var fileMap = new OrderedDictionary(StringComparer.OrdinalIgnoreCase); - foreach (ScriptFile file in referencedFiles) - { - fileMap.Add(file.FilePath, file); - } + // Make sure aliases have been loaded + await GetAliases(); - var allFiles = workspace.EnumeratePSFiles(); - foreach (var file in allFiles) + // We want to look for references first in referenced files, hence we use ordered dictionary + var fileMap = new OrderedDictionary(StringComparer.OrdinalIgnoreCase); + foreach (ScriptFile file in referencedFiles) + { + fileMap.Add(file.FilePath, file); + } + + IEnumerable allFiles = workspace.EnumeratePSFiles(); + foreach (string file in allFiles) + { + if (!fileMap.Contains(file)) { - if (!fileMap.Contains(file)) - { - fileMap.Add(file, new ScriptFile(file, null, this.powerShellContext.LocalPowerShellVersion.Version)); - } + fileMap.Add( + file, + new ScriptFile( + file, + clientFilePath: null, + powerShellVersion: this.powerShellContext.LocalPowerShellVersion.Version)); } + } - List symbolReferences = new List(); - foreach (var fileName in fileMap.Keys) - { - var file = (ScriptFile)fileMap[fileName]; - IEnumerable symbolReferencesinFile = - AstOperations - .FindReferencesOfSymbol( - file.ScriptAst, - foundSymbol, - CmdletToAliasDictionary, - AliasToCmdletDictionary) - .Select( - reference => + var symbolReferences = new List(); + foreach (object fileName in fileMap.Keys) + { + var file = (ScriptFile)fileMap[fileName]; + IEnumerable symbolReferencesinFile = + AstOperations + .FindReferencesOfSymbol( + file.ScriptAst, + foundSymbol, + CmdletToAliasDictionary, + AliasToCmdletDictionary) + .Select( + reference => + { + try { - try - { - reference.SourceLine = - file.GetLine(reference.ScriptRegion.StartLineNumber); - } - catch (ArgumentOutOfRangeException e) - { - reference.SourceLine = string.Empty; - this.logger.WriteException("Found reference is out of range in script file", e); - } - - reference.FilePath = file.FilePath; - return reference; - }); - - symbolReferences.AddRange(symbolReferencesinFile); - } + reference.SourceLine = file.GetLine(reference.ScriptRegion.StartLineNumber); + } + catch (ArgumentOutOfRangeException e) + { + reference.SourceLine = string.Empty; + this.logger.WriteException("Found reference is out of range in script file", e); + } - return - new FindReferencesResult - { - SymbolFileOffset = symbolOffset, - SymbolName = foundSymbol.SymbolName, - FoundReferences = symbolReferences - }; + reference.FilePath = file.FilePath; + return reference; + }); + + symbolReferences.AddRange(symbolReferencesinFile); } - else { return null; } + + return new FindReferencesResult + { + SymbolFileOffset = symbolOffset, + SymbolName = foundSymbol.SymbolName, + FoundReferences = symbolReferences + }; } /// From 700d4f6491c206806438fce85d47b51d7cede1e8 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Thu, 23 Aug 2018 16:50:05 -0700 Subject: [PATCH 2/4] Check that file exists before parsing for symbols --- .../Language/LanguageService.cs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/PowerShellEditorServices/Language/LanguageService.cs b/src/PowerShellEditorServices/Language/LanguageService.cs index d46faac2b..b5ca47716 100644 --- a/src/PowerShellEditorServices/Language/LanguageService.cs +++ b/src/PowerShellEditorServices/Language/LanguageService.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.IO; using System.Linq; using System.Management.Automation; using System.Management.Automation.Language; @@ -318,12 +319,21 @@ public async Task FindReferencesOfSymbol( { if (!fileMap.Contains(file)) { - fileMap.Add( - file, - new ScriptFile( + ScriptFile scriptFile; + try + { + scriptFile = new ScriptFile( file, clientFilePath: null, - powerShellVersion: this.powerShellContext.LocalPowerShellVersion.Version)); + powerShellVersion: this.powerShellContext.LocalPowerShellVersion.Version); + } + catch (IOException) + { + // If the file has ceased to exist for some reason, we just skip it + continue; + } + + fileMap.Add(file, scriptFile); } } @@ -338,8 +348,7 @@ public async Task FindReferencesOfSymbol( foundSymbol, CmdletToAliasDictionary, AliasToCmdletDictionary) - .Select( - reference => + .Select(reference => { try { From 5ba4f301f674367f00f7db84c4a43289f0ea92ac Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Fri, 24 Aug 2018 09:58:16 -0700 Subject: [PATCH 3/4] Fix unneccessary file read for workspace script files --- .../Language/LanguageService.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/PowerShellEditorServices/Language/LanguageService.cs b/src/PowerShellEditorServices/Language/LanguageService.cs index b5ca47716..f12d14ebc 100644 --- a/src/PowerShellEditorServices/Language/LanguageService.cs +++ b/src/PowerShellEditorServices/Language/LanguageService.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Management.Automation; using System.Management.Automation.Language; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -308,24 +309,23 @@ public async Task FindReferencesOfSymbol( await GetAliases(); // We want to look for references first in referenced files, hence we use ordered dictionary - var fileMap = new OrderedDictionary(StringComparer.OrdinalIgnoreCase); + // TODO: File system case-sensitivity is based on filesystem not OS, but OS is a much cheaper heuristic + var fileMap = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) + ? new OrderedDictionary() + : new OrderedDictionary(StringComparer.OrdinalIgnoreCase); foreach (ScriptFile file in referencedFiles) { fileMap.Add(file.FilePath, file); } - IEnumerable allFiles = workspace.EnumeratePSFiles(); - foreach (string file in allFiles) + foreach (string file in workspace.EnumeratePSFiles()) { if (!fileMap.Contains(file)) { ScriptFile scriptFile; try { - scriptFile = new ScriptFile( - file, - clientFilePath: null, - powerShellVersion: this.powerShellContext.LocalPowerShellVersion.Version); + scriptFile = workspace.GetFile(file); } catch (IOException) { From b5ad8cd8021d7bad40993dc0e38223d71cdb0988 Mon Sep 17 00:00:00 2001 From: Robert Holt Date: Tue, 28 Aug 2018 14:25:37 +1000 Subject: [PATCH 4/4] Fix unsupported API usage in .NET Framework --- src/PowerShellEditorServices/Language/LanguageService.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/PowerShellEditorServices/Language/LanguageService.cs b/src/PowerShellEditorServices/Language/LanguageService.cs index f12d14ebc..ff07acddd 100644 --- a/src/PowerShellEditorServices/Language/LanguageService.cs +++ b/src/PowerShellEditorServices/Language/LanguageService.cs @@ -310,9 +310,14 @@ public async Task FindReferencesOfSymbol( // We want to look for references first in referenced files, hence we use ordered dictionary // TODO: File system case-sensitivity is based on filesystem not OS, but OS is a much cheaper heuristic +#if CoreCLR + // The RuntimeInformation.IsOSPlatform is not supported in .NET Framework var fileMap = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? new OrderedDictionary() : new OrderedDictionary(StringComparer.OrdinalIgnoreCase); +#else + var fileMap = new OrderedDictionary(StringComparer.OrdinalIgnoreCase); +#endif foreach (ScriptFile file in referencedFiles) { fileMap.Add(file.FilePath, file);