/// <summary> /// Finds the parameter set hints of a specific command (determined by a given 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>ParameterSetSignatures</returns> public async Task <ParameterSetSignatures> FindParameterSetsInFile( ScriptFile file, int lineNumber, int columnNumber) { SymbolReference foundSymbol = AstOperations.FindCommandAtPosition( file.ScriptAst, lineNumber, columnNumber); if (foundSymbol != null) { CommandInfo commandInfo = await CommandHelpers.GetCommandInfo( foundSymbol.SymbolName, this.powerShellContext); if (commandInfo != null) { try { IEnumerable <CommandParameterSetInfo> commandParamSets = commandInfo.ParameterSets; return(new ParameterSetSignatures(commandParamSets, foundSymbol)); } catch (RuntimeException e) { // A RuntimeException will be thrown when an invalid attribute is // on a parameter binding block and then that command/script has // its signatures resolved by typing it into a script. this.logger.WriteException("RuntimeException encountered while accessing command parameter sets", e); return(null); } catch (InvalidOperationException) { // For some commands there are no paramsets (like applications). Until // the valid command types are better understood, catch this exception // which gets raised when there are no ParameterSets for the command type. return(null); } } else { return(null); } } else { return(null); } }
static internal async Task <SymbolDetails> CreateAsync( SymbolReference symbolReference, PowerShellContext powerShellContext) { SymbolDetails symbolDetails = new SymbolDetails(); symbolDetails.SymbolReference = symbolReference; // If the symbol is a command, get its documentation if (symbolReference.SymbolType == SymbolType.Function) { CommandInfo commandInfo = await CommandHelpers.GetCommandInfoAsync( symbolReference.SymbolName, powerShellContext); if (commandInfo != null) { symbolDetails.Documentation = await CommandHelpers.GetCommandSynopsisAsync( commandInfo, powerShellContext); if (commandInfo.CommandType == CommandTypes.Application) { symbolDetails.DisplayString = "(application) " + symbolReference.SymbolName; } else { symbolDetails.DisplayString = "function " + symbolReference.SymbolName; } } else { // Command information can't be loaded. This is likely due to // the symbol being a function that is defined in a file that // hasn't been loaded in the runspace yet. symbolDetails.DisplayString = "function " + symbolReference.SymbolName; } } else if (symbolReference.SymbolType == SymbolType.Parameter) { // TODO: Get parameter help symbolDetails.DisplayString = "(parameter) " + symbolReference.SymbolName; } else if (symbolReference.SymbolType == SymbolType.Variable) { symbolDetails.DisplayString = symbolReference.SymbolName; } return(symbolDetails); }
/// <summary> /// Finds the definition of a symbol in the script file or any of the /// files that it references. /// </summary> /// <param name="sourceFile">The initial script file to be searched for the symbol's definition.</param> /// <param name="foundSymbol">The symbol for which a definition will be found.</param> /// <param name="workspace">The Workspace to which the ScriptFile belongs.</param> /// <returns>The resulting GetDefinitionResult for the symbol's definition.</returns> public async Task <GetDefinitionResult> GetDefinitionOfSymbol( ScriptFile sourceFile, SymbolReference foundSymbol, Workspace workspace) { Validate.IsNotNull("sourceFile", sourceFile); Validate.IsNotNull("foundSymbol", foundSymbol); Validate.IsNotNull("workspace", workspace); ScriptFile[] referencedFiles = workspace.ExpandScriptReferences( sourceFile); // look through the referenced files until definition is found // or there are no more file to look through SymbolReference foundDefinition = null; for (int i = 0; i < referencedFiles.Length; i++) { foundDefinition = AstOperations.FindDefinitionOfSymbol( referencedFiles[i].ScriptAst, foundSymbol); if (foundDefinition != null) { foundDefinition.FilePath = referencedFiles[i].FilePath; break; } } // if definition is not found in referenced files // look for it in the builtin commands if (foundDefinition == null) { CommandInfo cmdInfo = await CommandHelpers.GetCommandInfo( foundSymbol.SymbolName, this.powerShellContext); foundDefinition = await FindDeclarationForBuiltinCommand( cmdInfo, foundSymbol, workspace); } return(foundDefinition != null ? new GetDefinitionResult(foundDefinition) : null); }
internal SymbolDetails( SymbolReference symbolReference, Runspace runspace) { this.SymbolReference = symbolReference; // If the symbol is a command, get its documentation if (symbolReference.SymbolType == SymbolType.Function) { CommandInfo commandInfo = CommandHelpers.GetCommandInfo( symbolReference.SymbolName, runspace); if (commandInfo != null) { this.Documentation = CommandHelpers.GetCommandSynopsis( commandInfo, runspace); if (commandInfo.CommandType == CommandTypes.Application) { this.DisplayString = "(application) " + symbolReference.SymbolName; } else { this.DisplayString = "function " + symbolReference.SymbolName; } } else { // Command information can't be loaded. This is likely due to // the symbol being a function that is defined in a file that // hasn't been loaded in the runspace yet. this.DisplayString = "function " + symbolReference.SymbolName; } } else if (symbolReference.SymbolType == SymbolType.Parameter) { // TODO: Get parameter help this.DisplayString = "(parameter) " + symbolReference.SymbolName; } else if (symbolReference.SymbolType == SymbolType.Variable) { this.DisplayString = symbolReference.SymbolName; } }
/// <summary> /// Finds the parameter set hints of a specific command (determined by a given 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>ParameterSetSignatures</returns> public async Task <ParameterSetSignatures> FindParameterSetsInFile( ScriptFile file, int lineNumber, int columnNumber) { SymbolReference foundSymbol = AstOperations.FindCommandAtPosition( file.ScriptAst, lineNumber, columnNumber); if (foundSymbol != null) { CommandInfo commandInfo = await CommandHelpers.GetCommandInfo( foundSymbol.SymbolName, this.powerShellContext); if (commandInfo != null) { try { IEnumerable <CommandParameterSetInfo> commandParamSets = commandInfo.ParameterSets; return(new ParameterSetSignatures(commandParamSets, foundSymbol)); } catch (InvalidOperationException) { // For some commands there are no paramsets (like applications). Until // the valid command types are better understood, catch this exception // which gets raised when there are no ParameterSets for the command type. return(null); } } else { return(null); } } else { return(null); } }
private async Task <SymbolReference> FindDeclarationForBuiltinCommand( CommandInfo cmdInfo, SymbolReference foundSymbol, Workspace workspace) { SymbolReference foundDefinition = null; if (cmdInfo != null) { int index = 0; ScriptFile[] nestedModuleFiles; CommandInfo commandInfo = await CommandHelpers.GetCommandInfo( foundSymbol.SymbolName, this.powerShellContext); nestedModuleFiles = GetBuiltinCommandScriptFiles( commandInfo.Module, workspace); while (foundDefinition == null && index < nestedModuleFiles.Length) { foundDefinition = AstOperations.FindDefinitionOfSymbol( nestedModuleFiles[index].ScriptAst, foundSymbol); if (foundDefinition != null) { foundDefinition.FilePath = nestedModuleFiles[index].FilePath; } index++; } } return(foundDefinition); }
/// <summary> /// Finds the definition of a symbol in the script file or any of the /// files that it references. /// </summary> /// <param name="sourceFile">The initial script file to be searched for the symbol's definition.</param> /// <param name="foundSymbol">The symbol for which a definition will be found.</param> /// <param name="workspace">The Workspace to which the ScriptFile belongs.</param> /// <returns>The resulting GetDefinitionResult for the symbol's definition.</returns> public async Task <GetDefinitionResult> GetDefinitionOfSymbol( ScriptFile sourceFile, SymbolReference foundSymbol, Workspace workspace) { Validate.IsNotNull("sourceFile", sourceFile); Validate.IsNotNull("foundSymbol", foundSymbol); Validate.IsNotNull("workspace", workspace); ScriptFile[] referencedFiles = workspace.ExpandScriptReferences( sourceFile); var filesSearched = new HashSet <string>(StringComparer.OrdinalIgnoreCase); // look through the referenced files until definition is found // or there are no more file to look through SymbolReference foundDefinition = null; for (int i = 0; i < referencedFiles.Length; i++) { foundDefinition = AstOperations.FindDefinitionOfSymbol( referencedFiles[i].ScriptAst, foundSymbol); filesSearched.Add(referencedFiles[i].FilePath); if (foundDefinition != null) { foundDefinition.FilePath = referencedFiles[i].FilePath; break; } } // if the definition the not found in referenced files // look for it in all the files in the workspace if (foundDefinition == null) { // Get a list of all powershell files in the workspace path var allFiles = workspace.EnumeratePSFiles(); foreach (var file in allFiles) { if (filesSearched.Contains(file)) { continue; } Token[] tokens = null; ParseError[] parseErrors = null; foundDefinition = AstOperations.FindDefinitionOfSymbol( Parser.ParseFile(file, out tokens, out parseErrors), foundSymbol); filesSearched.Add(file); if (foundDefinition != null) { foundDefinition.FilePath = file; break; } } } // if definition is not found in file in the workspace // look for it in the builtin commands if (foundDefinition == null) { CommandInfo cmdInfo = await CommandHelpers.GetCommandInfo( foundSymbol.SymbolName, this.powerShellContext); foundDefinition = FindDeclarationForBuiltinCommand( cmdInfo, foundSymbol, workspace); } return(foundDefinition != null ? new GetDefinitionResult(foundDefinition) : null); }
/// <summary> /// Finds the definition of a symbol in the script file or any of the /// files that it references. /// </summary> /// <param name="sourceFile">The initial script file to be searched for the symbol's definition.</param> /// <param name="foundSymbol">The symbol for which a definition will be found.</param> /// <param name="workspace">The Workspace to which the ScriptFile belongs.</param> /// <returns>The resulting GetDefinitionResult for the symbol's definition.</returns> public async Task <GetDefinitionResult> GetDefinitionOfSymbolAsync( ScriptFile sourceFile, SymbolReference foundSymbol, Workspace workspace) { Validate.IsNotNull(nameof(sourceFile), sourceFile); Validate.IsNotNull(nameof(foundSymbol), foundSymbol); Validate.IsNotNull(nameof(workspace), workspace); ScriptFile[] referencedFiles = workspace.ExpandScriptReferences( sourceFile); var filesSearched = new HashSet <string>(StringComparer.OrdinalIgnoreCase); // look through the referenced files until definition is found // or there are no more file to look through SymbolReference foundDefinition = null; foreach (ScriptFile scriptFile in referencedFiles) { foundDefinition = AstOperations.FindDefinitionOfSymbol( scriptFile.ScriptAst, foundSymbol); filesSearched.Add(scriptFile.FilePath); if (foundDefinition != null) { foundDefinition.FilePath = scriptFile.FilePath; break; } if (foundSymbol.SymbolType == SymbolType.Function) { // Dot-sourcing is parsed as a "Function" Symbol. string dotSourcedPath = GetDotSourcedPath(foundSymbol, workspace, scriptFile); if (scriptFile.FilePath == dotSourcedPath) { foundDefinition = new SymbolReference(SymbolType.Function, foundSymbol.SymbolName, scriptFile.ScriptAst.Extent, scriptFile.FilePath); break; } } } // if the definition the not found in referenced files // look for it in all the files in the workspace if (foundDefinition == null) { // Get a list of all powershell files in the workspace path IEnumerable <string> allFiles = workspace.EnumeratePSFiles(); foreach (string file in allFiles) { if (filesSearched.Contains(file)) { continue; } Token[] tokens = null; ParseError[] parseErrors = null; foundDefinition = AstOperations.FindDefinitionOfSymbol( Parser.ParseFile(file, out tokens, out parseErrors), foundSymbol); filesSearched.Add(file); if (foundDefinition != null) { foundDefinition.FilePath = file; break; } } } // if definition is not found in file in the workspace // look for it in the builtin commands if (foundDefinition == null) { CommandInfo cmdInfo = await CommandHelpers.GetCommandInfoAsync( foundSymbol.SymbolName, _powerShellContext); foundDefinition = FindDeclarationForBuiltinCommand( cmdInfo, foundSymbol, workspace); } return(foundDefinition != null ? new GetDefinitionResult(foundDefinition) : null); }