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 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> FindParameterSetsInFileAsync( ScriptFile file, int lineNumber, int columnNumber) { SymbolReference foundSymbol = AstOperations.FindCommandAtPosition( file.ScriptAst, lineNumber, columnNumber); if (foundSymbol == null) { return(null); } CommandInfo commandInfo = await CommandHelpers.GetCommandInfoAsync( foundSymbol.SymbolName, _powerShellContext); if (commandInfo == null) { return(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. _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); } }
/// <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); }