/// <summary>
        /// Finds all the occurences of a symbol in the script given a file location
        /// </summary>
        /// <param name="file">The details and contents of a open script file</param>
        /// <param name="lineNumber">The line number of the cursor for the given script</param>
        /// <param name="columnNumber">The coulumn number of the cursor for the given script</param>
        /// <returns>FindOccurrencesResult</returns>
        public FindOccurrencesResult FindOccurrencesInFile(
            ScriptFile file,
            int lineNumber,
            int columnNumber)
        {
            SymbolReference foundSymbol =
                AstOperations.FindSymbolAtPosition(
                    file.ScriptAst,
                    lineNumber,
                    columnNumber);

            if (foundSymbol != null)
            {
                // find all references, and indicate that looking for aliases is not needed
                IEnumerable <SymbolReference> symbolOccurrences =
                    AstOperations
                    .FindReferencesOfSymbol(
                        file.ScriptAst,
                        foundSymbol,
                        false);

                return
                    (new FindOccurrencesResult
                {
                    FoundOccurrences = symbolOccurrences
                });
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Finds all the references of a symbol
        /// </summary>
        /// <param name="foundSymbol">The symbol to find all references for</param>
        /// <param name="referencedFiles">An array of scriptFiles too search for references in</param>
        /// <returns>FindReferencesResult</returns>
        public async Task <FindReferencesResult> FindReferencesOfSymbol(
            SymbolReference foundSymbol,
            ScriptFile[] referencedFiles)
        {
            if (foundSymbol != null)
            {
                int symbolOffset = referencedFiles[0].GetOffsetAtPosition(
                    foundSymbol.ScriptRegion.StartLineNumber,
                    foundSymbol.ScriptRegion.StartColumnNumber);

                // Make sure aliases have been loaded
                await GetAliases();

                List <SymbolReference> symbolReferences = new List <SymbolReference>();
                foreach (ScriptFile file in referencedFiles)
                {
                    IEnumerable <SymbolReference> symbolReferencesinFile =
                        AstOperations
                        .FindReferencesOfSymbol(
                            file.ScriptAst,
                            foundSymbol,
                            CmdletToAliasDictionary,
                            AliasToCmdletDictionary)
                        .Select(
                            reference =>
                    {
                        reference.SourceLine =
                            file.GetLine(reference.ScriptRegion.StartLineNumber);
                        reference.FilePath = file.FilePath;
                        return(reference);
                    });

                    symbolReferences.AddRange(symbolReferencesinFile);
                }

                return
                    (new FindReferencesResult
                {
                    SymbolFileOffset = symbolOffset,
                    SymbolName = foundSymbol.SymbolName,
                    FoundReferences = symbolReferences
                });
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Finds all the references of a symbol
        /// </summary>
        /// <param name="foundSymbol">The symbol to find all references for</param>
        /// <param name="referencedFiles">An array of scriptFiles too search for references in</param>
        /// <param name="workspace">The workspace that will be searched for symbols</param>
        /// <returns>FindReferencesResult</returns>
        public async Task <FindReferencesResult> FindReferencesOfSymbol(
            SymbolReference foundSymbol,
            ScriptFile[] referencedFiles,
            Workspace workspace)
        {
            if (foundSymbol != null)
            {
                int symbolOffset = referencedFiles[0].GetOffsetAtPosition(
                    foundSymbol.ScriptRegion.StartLineNumber,
                    foundSymbol.ScriptRegion.StartColumnNumber);

                // Make sure aliases have been loaded
                await GetAliases();

                // 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);
                }

                var allFiles = workspace.EnumeratePSFiles();
                foreach (var file in allFiles)
                {
                    if (!fileMap.Contains(file))
                    {
                        fileMap.Add(file, new ScriptFile(file, null, this.powerShellContext.LocalPowerShellVersion.Version));
                    }
                }

                List <SymbolReference> symbolReferences = new List <SymbolReference>();
                foreach (var fileName in fileMap.Keys)
                {
                    var file = (ScriptFile)fileMap[fileName];
                    IEnumerable <SymbolReference> symbolReferencesinFile =
                        AstOperations
                        .FindReferencesOfSymbol(
                            file.ScriptAst,
                            foundSymbol,
                            CmdletToAliasDictionary,
                            AliasToCmdletDictionary)
                        .Select(
                            reference =>
                    {
                        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);
                }

                return
                    (new FindReferencesResult
                {
                    SymbolFileOffset = symbolOffset,
                    SymbolName = foundSymbol.SymbolName,
                    FoundReferences = symbolReferences
                });
            }
            else
            {
                return(null);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Finds all the references of a symbol
        /// </summary>
        /// <param name="foundSymbol">The symbol to find all references for</param>
        /// <param name="referencedFiles">An array of scriptFiles too search for references in</param>
        /// <param name="workspace">The workspace that will be searched for symbols</param>
        /// <returns>FindReferencesResult</returns>
        public async Task <FindReferencesResult> FindReferencesOfSymbolAsync(
            SymbolReference foundSymbol,
            ScriptFile[] referencedFiles,
            Workspace workspace)
        {
            if (foundSymbol == null)
            {
                return(null);
            }

            int symbolOffset = referencedFiles[0].GetOffsetAtPosition(
                foundSymbol.ScriptRegion.StartLineNumber,
                foundSymbol.ScriptRegion.StartColumnNumber);

            // Make sure aliases have been loaded
            await GetAliasesAsync();

            // 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
            var fileMap = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
                ? new OrderedDictionary()
                : new OrderedDictionary(StringComparer.OrdinalIgnoreCase);

            foreach (ScriptFile scriptFile in referencedFiles)
            {
                fileMap[scriptFile.FilePath] = scriptFile;
            }

            foreach (string filePath in workspace.EnumeratePSFiles())
            {
                if (!fileMap.Contains(filePath))
                {
                    if (!workspace.TryGetFile(filePath, out ScriptFile scriptFile))
                    {
                        // If we can't access the file for some reason, just ignore it
                        continue;
                    }

                    fileMap[filePath] = scriptFile;
                }
            }

            var symbolReferences = new List <SymbolReference>();

            foreach (object fileName in fileMap.Keys)
            {
                var file = (ScriptFile)fileMap[fileName];
                await _aliasHandle.WaitAsync();

                try
                {
                    IEnumerable <SymbolReference> references = AstOperations.FindReferencesOfSymbol(
                        file.ScriptAst,
                        foundSymbol,
                        _cmdletToAliasDictionary,
                        _aliasToCmdletDictionary);

                    foreach (SymbolReference reference in references)
                    {
                        try
                        {
                            reference.SourceLine = file.GetLine(reference.ScriptRegion.StartLineNumber);
                        }
                        catch (ArgumentOutOfRangeException e)
                        {
                            reference.SourceLine = string.Empty;
                            _logger.WriteException("Found reference is out of range in script file", e);
                        }
                        reference.FilePath = file.FilePath;
                        symbolReferences.Add(reference);
                    }
                }
                finally
                {
                    _aliasHandle.Release();
                }
            }

            return(new FindReferencesResult
            {
                SymbolFileOffset = symbolOffset,
                SymbolName = foundSymbol.SymbolName,
                FoundReferences = symbolReferences
            });
        }
Esempio n. 5
0
        /// <summary>
        /// Finds all the references of a symbol
        /// </summary>
        /// <param name="foundSymbol">The symbol to find all references for</param>
        /// <param name="referencedFiles">An array of scriptFiles too search for references in</param>
        /// <param name="workspace">The workspace that will be searched for symbols</param>
        /// <returns>FindReferencesResult</returns>
        public async Task <FindReferencesResult> FindReferencesOfSymbol(
            SymbolReference foundSymbol,
            ScriptFile[] referencedFiles,
            Workspace workspace)
        {
            if (foundSymbol == null)
            {
                return(null);
            }

            int symbolOffset = referencedFiles[0].GetOffsetAtPosition(
                foundSymbol.ScriptRegion.StartLineNumber,
                foundSymbol.ScriptRegion.StartColumnNumber);

            // Make sure aliases have been loaded
            await GetAliases();

            // 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);
            }

            foreach (string file in workspace.EnumeratePSFiles())
            {
                if (!fileMap.Contains(file))
                {
                    ScriptFile scriptFile;
                    try
                    {
                        scriptFile = workspace.GetFile(file);
                    }
                    catch (Exception e) when(e is IOException ||
                                             e is SecurityException ||
                                             e is FileNotFoundException ||
                                             e is DirectoryNotFoundException ||
                                             e is PathTooLongException ||
                                             e is UnauthorizedAccessException)
                    {
                        // If we can't access the file for some reason, just ignore it
                        continue;
                    }

                    fileMap.Add(file, scriptFile);
                }
            }

            var symbolReferences = new List <SymbolReference>();
            foreach (object fileName in fileMap.Keys)
            {
                var file = (ScriptFile)fileMap[fileName];

                IEnumerable <SymbolReference> references = AstOperations.FindReferencesOfSymbol(
                    file.ScriptAst,
                    foundSymbol,
                    _cmdletToAliasDictionary,
                    _aliasToCmdletDictionary);

                foreach (SymbolReference reference in references)
                {
                    try
                    {
                        reference.SourceLine = file.GetLine(reference.ScriptRegion.StartLineNumber);
                    }
                    catch (ArgumentOutOfRangeException e)
                    {
                        reference.SourceLine = string.Empty;
                        _logger.WriteException("Found reference is out of range in script file", e);
                    }
                    reference.FilePath = file.FilePath;
                    symbolReferences.Add(reference);
                }
            }

            return(new FindReferencesResult
            {
                SymbolFileOffset = symbolOffset,
                SymbolName = foundSymbol.SymbolName,
                FoundReferences = symbolReferences
            });
        }