/// <summary> /// Create an instance of DiagnosticRecord and add it to a list /// </summary> private void GenerateDiagnosticRecords() { foreach (var curCmdletCompat in curCmdletCompatibilityMap) { if (!curCmdletCompat.Value) { var cmdletName = curCmdletAst.GetCommandName(); var platformInfo = platformSpecMap[curCmdletCompat.Key]; var funcNameTokens = Helper.Instance.Tokens.Where( token => Helper.ContainsExtent(curCmdletAst.Extent, token.Extent) && token.Text.Equals(cmdletName)); var funcNameToken = funcNameTokens.FirstOrDefault(); var extent = funcNameToken == null ? null : funcNameToken.Extent; diagnosticRecords.Add(new DiagnosticRecord( String.Format( Strings.UseCompatibleCmdletsError, cmdletName, platformInfo.PSEdition, platformInfo.PSVersion, platformInfo.OS), extent, GetName(), GetDiagnosticSeverity(), scriptPath, null, null)); } } }
/// <summary> /// AnalyzeScript: Analyze the ast to check that positional parameters are not used. /// </summary> public IEnumerable <DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) { if (ast == null) { throw new ArgumentNullException(Strings.NullAstErrorMessage); } // Finds all CommandAsts. IEnumerable <Ast> foundAsts = ast.FindAll(testAst => testAst is CommandAst, true); // Iterrates all CommandAsts and check the command name. foreach (Ast foundAst in foundAsts) { CommandAst cmdAst = (CommandAst)foundAst; // Handles the exception caused by commands like, {& $PLINK $args 2> $TempErrorFile}. // You can also review the remark section in following document, // MSDN: CommandAst.GetCommandName Method if (cmdAst.GetCommandName() == null) { continue; } if (Helper.Instance.GetCommandInfo(cmdAst.GetCommandName()) != null && Helper.Instance.PositionalParameterUsed(cmdAst)) { yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingPositionalParametersError, cmdAst.GetCommandName()), cmdAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, cmdAst.GetCommandName())); } } }
/// <summary> /// Checks that write-host command is not used /// </summary> /// <param name="cmdAst"></param> /// <returns></returns> public override AstVisitAction VisitCommand(CommandAst cmdAst) { if (cmdAst == null) { return(AstVisitAction.SkipChildren); } if (cmdAst.GetCommandName() != null && String.Equals(cmdAst.GetCommandName(), "write-host", StringComparison.OrdinalIgnoreCase)) { records.Add(new DiagnosticRecord(String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingWriteHostError, System.IO.Path.GetFileName(fileName)), cmdAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName)); } return(AstVisitAction.Continue); }
private static IEnumerable <FunctionDefinitionAst> FindDefinition(CommandAst reference) { var scope = GetParentScope(reference); if (scope != null) { // If in the same scope as the reference call, the function must be defined before the call var definitions = scope.Statements.OfType <FunctionDefinitionAst>(). Where(def => def.Name.Equals(reference.GetCommandName(), StringComparison.OrdinalIgnoreCase) && def.Extent.EndOffset <= reference.Extent.StartOffset); if (definitions.Any()) { // Since we are in the same scope as the reference, we always go to the last function defined before the call return(new List <FunctionDefinitionAst>() { definitions.Last() }); } while ((scope = GetParentScope(scope)) != null) { definitions = scope.Statements.OfType <FunctionDefinitionAst>().Where(def => def.Name.Equals(reference.GetCommandName(), StringComparison.OrdinalIgnoreCase)); if (definitions.Any()) { return(new List <FunctionDefinitionAst>(definitions)); } } } return(null); }
public override AstVisitAction VisitCommand(CommandAst commandAst) { var name = commandAst.GetCommandName(); var elements = commandAst.CommandElements.Skip(1).ToArray(); var arguments = new List <Argument>(); for (var i = 0; i < elements.Length; i++) { var node = VisitSyntaxNode(elements[i]); var argument = node as Argument; if (argument != null && i < elements.Length - 1 && argument.Expression == null) { node = VisitSyntaxNode(elements[i + 1]); argument.Expression = node; i++; } else if (argument == null) { argument = new Argument(node); } arguments.Add(argument); } _currentNode = ConvertCommand(new Invocation(new IdentifierName(name), new ArgumentList(arguments))); return(AstVisitAction.SkipChildren); }
public override AstVisitAction VisitCommand(CommandAst commandAst) { string commandName = commandAst.GetCommandName(); if (commandName == null) { UnsupportedError("Could not get command name", commandAst.Extent); return(base.VisitCommand(commandAst)); } if (commandAst.InvocationOperator == TokenKind.Dot) { AnalyzeDotSourcedFile(commandName); } else if (commandName == "Import-Module" || commandName == "ipmo") { // TODO } else { AnalyzeCommandInvocation(commandAst, commandName); } return(base.VisitCommand(commandAst)); }
/// <summary> /// AnalyzeScript: Analyze the script to check if cmdlet alias is used. /// </summary> public IEnumerable <DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) { if (ast == null) { throw new ArgumentNullException(Strings.NullAstErrorMessage); } // Finds all CommandAsts. IEnumerable <Ast> foundAsts = ast.FindAll(testAst => testAst is CommandAst, true); // Iterrates all CommandAsts and check the command name. foreach (Ast foundAst in foundAsts) { CommandAst cmdAst = (CommandAst)foundAst; string aliasName = cmdAst.GetCommandName(); // Handles the exception caused by commands like, {& $PLINK $args 2> $TempErrorFile}. // You can also review the remark section in following document, // MSDN: CommandAst.GetCommandName Method if (aliasName == null) { continue; } string cmdletName = Microsoft.Windows.Powershell.ScriptAnalyzer.Helper.Instance.GetCmdletNameFromAlias(aliasName); if (!String.IsNullOrEmpty(cmdletName)) { yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingCmdletAliasesError, aliasName, cmdletName), cmdAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, aliasName)); } } }
/// <summary> /// Creates a list containing suggested correction /// </summary> /// <param name="cmdAst">Command AST of an alias</param> /// <param name="cmdletName">Full name of the alias</param> /// <returns>Retruns a list of suggested corrections</returns> private List <CorrectionExtent> GetCorrectionExtent(CommandAst cmdAst, string cmdletName) { var ext = cmdAst.Extent; if (ext.File == null) { return(null); } var corrections = new List <CorrectionExtent>(); var alias = cmdAst.GetCommandName(); string description = string.Format( CultureInfo.CurrentCulture, Strings.AvoidUsingCmdletAliasesCorrectionDescription, alias, cmdletName); corrections.Add(new CorrectionExtent( ext.StartLineNumber, ext.EndLineNumber, cmdAst.CommandElements[0].Extent.StartColumnNumber, cmdAst.CommandElements[0].Extent.EndColumnNumber, cmdletName, ext.File, description)); return(corrections); }
public override AstVisitAction VisitCommandParameter(CommandParameterAst commandParameterAst) { CommandAst commandParentAst = commandParameterAst.Parent as CommandAst; if (commandParentAst != null && String.Equals(commandParentAst.GetCommandName(), "Import-DscResource", StringComparison.OrdinalIgnoreCase)) { // Resource can be specified by name, without a module. if (String.Equals(commandParameterAst.ParameterName, "Name", StringComparison.OrdinalIgnoreCase)) { ArrayLiteralAst arrayLiteralAst = commandParameterAst.Argument as ArrayLiteralAst; if (arrayLiteralAst != null) { IEnumerable <string> resourceNames = arrayLiteralAst.Elements.OfType <StringConstantExpressionAst>().Select(x => x.Value); foreach (string resourceName in resourceNames) { } } } // Or with ModuleDefinition parameter else if (String.Equals(commandParameterAst.ParameterName, "ModuleDefinition", StringComparison.OrdinalIgnoreCase)) { ArrayLiteralAst arrayLiteralAst = commandParameterAst.Argument as ArrayLiteralAst; if (arrayLiteralAst != null) { Modules.AddRange(arrayLiteralAst.Elements.OfType <StringConstantExpressionAst>().Select(x => x.Value)); } } } return(base.VisitCommandParameter(commandParameterAst)); }
public override StatementAst VisitCommand(CommandAst commandAst) { string commandName; if (commandAst.InvocationOperator != TokenKind.Dot || commandAst.CommandElements.Count != 1) { return(base.VisitCommand(commandAst)); } if (!string.IsNullOrEmpty(commandName = commandAst.GetCommandName())) { if (IsScriptFile(commandName)) { var wasSuccessful = TryCreateScriptBlockExpression( commandName, commandAst.Extent, out StatementAst result); return(wasSuccessful ? result : base.VisitCommand(commandAst)); } } return(base.VisitCommand(commandAst)); }
/// <summary> /// Determines if CommandAst is for the "New-Alias" command, checking aliases. /// </summary> /// <param name="commandAst">CommandAst to validate</param> /// <returns>True if the CommandAst is for the "New-Alias" command</returns> private bool IsNewAliasCmdlet(CommandAst commandAst) { if (commandAst == null || commandAst.GetCommandName() == null) { return(false); } var AliasList = Helper.Instance.CmdletNameAndAliases("New-Alias"); if (AliasList.Contains(commandAst.GetCommandName())) { return(true); } return(false); }
public override AstVisitAction VisitCommand(CommandAst commandAst) //confirmed { if (commandAst.ToString().Contains(symbolRef.ScriptRegion.Text)) { ValidateExtend(symbolRef.ScriptRegion.Text, commandAst.GetCommandName(), commandAst); } return(base.VisitCommand(commandAst)); }
public static bool HasProxyCommand(CommandAst commandAst) { var commandName = commandAst.GetCommandName(); var assembly = Assembly.GetExecutingAssembly(); var resourceName = $"CodeConverter.PowerShell.ProxyCommands.{commandName}.ps1"; return(assembly.GetManifestResourceStream(resourceName) != null); }
public override AstVisitAction VisitCommand(CommandAst commandAst) { var name = commandAst.GetCommandName(); var elements = commandAst.CommandElements.Skip(1).ToArray(); var arguments = new List <Argument>(); if (ParameterFinder.HasProxyCommand(commandAst)) { arguments = new List <Argument>(); var parameters = ParameterFinder.FindBoundParameters(commandAst); foreach (var parameter in parameters) { if (parameter.Value is Ast) { var ast = parameter.Value as Ast; var node = VisitSyntaxNode(ast); var argument = new Argument(parameter.Key, node); arguments.Add(argument); } else if (parameter.Value is ExpressionAst[]) { var ast = (parameter.Value as ExpressionAst[]).First(); var node = VisitSyntaxNode(ast); var argument = new Argument(parameter.Key, node); arguments.Add(argument); } else { var literal = new Literal(parameter.Value.ToString()); var argument = new Argument(parameter.Key, literal); arguments.Add(argument); } } } else { for (var i = 0; i < elements.Length; i++) { var node = VisitSyntaxNode(elements[i]); var argument = node as Argument; if (argument != null && i < elements.Length - 1 && argument.Expression == null) { node = VisitSyntaxNode(elements[i + 1]); argument.Expression = node; i++; } else if (argument == null) { argument = new Argument(node); } arguments.Add(argument); } } _currentNode = ConvertCommand(new Invocation(new IdentifierName(name), new ArgumentList(arguments))); return(AstVisitAction.SkipChildren); }
/// <summary> /// AnalyzeScript: Analyze the ast to check that positional parameters are not used. /// </summary> public IEnumerable <DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) { if (ast == null) { throw new ArgumentNullException(Strings.NullAstErrorMessage); } // Find all function definitions in the script and add them to the set. IEnumerable <Ast> functionDefinitionAsts = ast.FindAll(testAst => testAst is FunctionDefinitionAst, true); HashSet <String> declaredFunctionNames = new HashSet <String>(); foreach (FunctionDefinitionAst functionDefinitionAst in functionDefinitionAsts) { if (string.IsNullOrEmpty(functionDefinitionAst.Name)) { continue; } declaredFunctionNames.Add(functionDefinitionAst.Name); } // Finds all CommandAsts. IEnumerable <Ast> foundAsts = ast.FindAll(testAst => testAst is CommandAst, true); // Iterates all CommandAsts and check the command name. foreach (Ast foundAst in foundAsts) { CommandAst cmdAst = (CommandAst)foundAst; // Handles the exception caused by commands like, {& $PLINK $args 2> $TempErrorFile}. // You can also review the remark section in following document, // MSDN: CommandAst.GetCommandName Method if (cmdAst.GetCommandName() == null) { continue; } if ((Helper.Instance.IsCmdlet(cmdAst) || declaredFunctionNames.Contains(cmdAst.GetCommandName())) && (Helper.Instance.PositionalParameterUsed(cmdAst, true))) { PipelineAst parent = cmdAst.Parent as PipelineAst; if (parent != null && parent.PipelineElements.Count > 1) { // raise if it's the first element in pipeline. otherwise no. if (parent.PipelineElements[0] == cmdAst) { yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingPositionalParametersError, cmdAst.GetCommandName()), cmdAst.Extent, GetName(), DiagnosticSeverity.Information, fileName, cmdAst.GetCommandName())); } } // not in pipeline so just raise it normally else { yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingPositionalParametersError, cmdAst.GetCommandName()), cmdAst.Extent, GetName(), DiagnosticSeverity.Information, fileName, cmdAst.GetCommandName())); } } } }
/// <summary> /// Condition on the cmdlet that must be satisfied for the error to be raised /// </summary> /// <param name="CmdAst"></param> /// <returns></returns> public override bool CommandCondition(CommandAst CmdAst) { if (CTSTCmdlet == null) { CTSTCmdlet = Helper.Instance.CmdletNameAndAliases("convertto-securestring"); } return(CmdAst != null && CmdAst.GetCommandName() != null && CTSTCmdlet.Contains(CmdAst.GetCommandName(), StringComparer.OrdinalIgnoreCase)); }
/// <summary> /// Test if the given Ast is a regular CommandAst with arguments /// </summary> /// <param name="ast">the PowerShell Ast to test</param> /// <returns>true if the Ast represents a PowerShell command with arguments, false otherwise</returns> private static bool IsNamedCommandWithArguments(Ast ast) { CommandAst commandAst = ast as CommandAst; return(commandAst != null && commandAst.InvocationOperator != TokenKind.Dot && PesterSymbolReference.GetCommandType(commandAst.GetCommandName()).HasValue&& commandAst.CommandElements.Count >= 2); }
/// <summary> /// Attempt to process a <see cref="CommandAst" /> as a custom command. /// </summary> /// <param name="commandAst">The <see cref="CommandAst" /> to process.</param> /// <param name="visitor"> /// The <see cref="CompileVisitor" /> requesting the expression. /// </param> /// <param name="expression"> /// The <see cref="Expression" /> result if a command handler was found. /// </param> /// <returns><c>true</c> if a commmand handler was matched, otherwise <c>false</c>.</returns> public bool TryProcessAst(CommandAst commandAst, CompileVisitor visitor, out Expression expression) { if (_commandRegistry.TryGetValue(commandAst.GetCommandName(), out ICommandHandler handler)) { expression = handler.ProcessAst(commandAst, visitor); return(true); } expression = null; return(false); }
public override AstVisitAction VisitCommand(CommandAst commandAst) { string commandName = commandAst?.GetCommandName(); if (commandName == null) { return(AstVisitAction.Continue); } if (_commandsToIgnore.Contains(commandName)) { return(AstVisitAction.Continue); } // Note: // The "right" way to eliminate user-defined commands would be to build // a list of: // - all functions defined above this point // - all modules imported // However, looking for imported modules could prove very expensive // and we would still miss things like assignments to the function: provider. // Instead, we look to see if a command of the given name is present in any // known profile, which is something of a hack. // This is not present in any known profiles, so assume it is user defined if (!_anyProfile.Runtime.Commands.ContainsKey(commandName)) { return(AstVisitAction.Continue); } // Check each target platform foreach (CompatibilityProfileData targetProfile in _compatibilityTargets) { // If the target has this command, everything is good if (targetProfile.Runtime.Commands.TryGetValue(commandName, out IReadOnlyList <CommandData> matchedCommands)) { // Now check that the parameters on the command are available on all target platforms CheckCommandInvocationParameters(targetProfile, commandName, commandAst, matchedCommands); continue; } var diagnostic = CommandCompatibilityDiagnostic.Create( commandName, targetProfile.Platform, commandAst.Extent, _analyzedFileName, _rule); _diagnosticAccumulator.Add(diagnostic); } return(AstVisitAction.Continue); }
/// <summary> /// Create an instance of DiagnosticRecord and add it to a list /// </summary> private void GenerateDiagnosticRecords() { bool referenceCompatibility = curCmdletCompatibilityMap[reference]; // If the command is present in reference platform but not in any of the target platforms. // Or if the command is not present in reference platform but present in any of the target platforms // then declare it as an incompatible cmdlet. // If it is present neither in reference platform nor any target platforms, then it is probably a // non-builtin command and hence do not declare it as an incompatible cmdlet. // Since we do not check for aliases, the XOR-ing will also make sure that aliases are not flagged // as they will be found neither in reference platform nor in target platforms foreach (var platform in ruleParameters.compatibility) { var curCmdletCompat = curCmdletCompatibilityMap[platform]; if (!curCmdletCompat && referenceCompatibility) { var cmdletName = curCmdletAst.GetCommandName(); var platformInfo = platformSpecMap[platform]; var funcNameTokens = Helper.Instance.Tokens.Where( token => Helper.ContainsExtent(curCmdletAst.Extent, token.Extent) && token.Text.Equals(cmdletName)); var funcNameToken = funcNameTokens.FirstOrDefault(); var extent = funcNameToken == null ? null : funcNameToken.Extent; diagnosticRecords.Add(new DiagnosticRecord( String.Format( Strings.UseCompatibleCmdletsError, cmdletName, platformInfo.PSEdition, platformInfo.PSVersion, platformInfo.OS), extent, GetName(), GetDiagnosticSeverity(), scriptPath, null, null)); } } }
Command GetCommand(CommandAst commandAst) { if (commandAst.CommandElements.First() is ScriptBlockExpressionAst) { var scriptBlockAst = (commandAst.CommandElements.First() as ScriptBlockExpressionAst).ScriptBlock; return(new Command(scriptBlockAst)); } else { return(new Command(commandAst.GetCommandName())); } }
/// <summary> /// AnalyzeScript: Analyze the script to check if cmdlet alias is used. /// </summary> public IEnumerable <DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) { if (ast == null) { throw new ArgumentNullException(Strings.NullAstErrorMessage); } if (!isPropertiesSet) { SetProperties(); } // Finds all CommandAsts. IEnumerable <Ast> foundAsts = ast.FindAll(testAst => testAst is CommandAst, true); // Iterates all CommandAsts and check the command name. foreach (Ast foundAst in foundAsts) { CommandAst cmdAst = (CommandAst)foundAst; // Check if the command ast should be ignored if (IgnoreCommandast(cmdAst)) { continue; } string aliasName = cmdAst.GetCommandName(); // Handles the exception caused by commands like, {& $PLINK $args 2> $TempErrorFile}. // You can also review the remark section in following document, // MSDN: CommandAst.GetCommandName Method if (aliasName == null || whiteList.Contains(aliasName)) { continue; } string cmdletName = Helper.Instance.GetCmdletNameFromAlias(aliasName); if (!String.IsNullOrEmpty(cmdletName)) { yield return(new DiagnosticRecord( string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingCmdletAliasesError, aliasName, cmdletName), GetCommandExtent(cmdAst), GetName(), DiagnosticSeverity.Warning, fileName, aliasName, suggestedCorrections: GetCorrectionExtent(cmdAst, cmdletName))); } } }
/// <summary> /// Convert a CommandAst known to represent a Pester command and a reference to the scriptfile /// it is in into symbol representing a Pester call for code lens /// </summary> /// <param name="scriptFile">the scriptfile the Pester call occurs in</param> /// <param name="pesterCommandAst">the CommandAst representing the Pester call</param> /// <returns>a symbol representing the Pester call containing metadata for CodeLens to use</returns> private static PesterSymbolReference ConvertPesterAstToSymbolReference(ScriptFile scriptFile, CommandAst pesterCommandAst) { string testLine = scriptFile.GetLine(pesterCommandAst.Extent.StartLineNumber); PesterCommandType?commandName = PesterSymbolReference.GetCommandType(pesterCommandAst.GetCommandName()); if (commandName == null) { return(null); } // Search for a name for the test // If the test has more than one argument for names, we set it to null string testName = null; bool alreadySawName = false; for (int i = 1; i < pesterCommandAst.CommandElements.Count; i++) { CommandElementAst currentCommandElement = pesterCommandAst.CommandElements[i]; // Check for an explicit "-Name" parameter if (currentCommandElement is CommandParameterAst) { // Found -Name parameter, move to next element which is the argument for -TestName i++; if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName)) { alreadySawName = true; } continue; } // Otherwise, if an argument is given with no parameter, we assume it's the name // If we've already seen a name, we set the name to null if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName)) { alreadySawName = true; } } return(new PesterSymbolReference( scriptFile, commandName.Value, testLine, testName, pesterCommandAst.Extent )); }
/// <summary> /// Convert a CommandAst known to represent a Pester command and a reference to the scriptfile /// it is in into symbol representing a Pester call for code lens /// </summary> /// <param name="scriptFile">the scriptfile the Pester call occurs in</param> /// <param name="pesterCommandAst">the CommandAst representing the Pester call</param> /// <returns>a symbol representing the Pester call containing metadata for CodeLens to use</returns> private static PesterSymbolReference ConvertPesterAstToSymbolReference(ScriptFile scriptFile, CommandAst pesterCommandAst) { string testLine = scriptFile.GetLine(pesterCommandAst.Extent.StartLineNumber); PesterCommandType?commandName = PesterSymbolReference.GetCommandType(pesterCommandAst.GetCommandName()); if (commandName == null) { return(null); } // Search for a name for the test // If the test has more than one argument for names, we set it to null string testName = null; bool alreadySawName = false; for (int i = 1; i < pesterCommandAst.CommandElements.Count; i++) { CommandElementAst currentCommandElement = pesterCommandAst.CommandElements[i]; // Check for an explicit "-Name" parameter if (currentCommandElement is CommandParameterAst parameterAst) { i++; if (parameterAst.ParameterName == "Name" && i < pesterCommandAst.CommandElements.Count) { testName = alreadySawName ? null : (pesterCommandAst.CommandElements[i] as StringConstantExpressionAst)?.Value; alreadySawName = true; } continue; } // Otherwise, if an argument is given with no parameter, we assume it's the name // If we've already seen a name, we set the name to null if (pesterCommandAst.CommandElements[i] is StringConstantExpressionAst testNameStrAst) { testName = alreadySawName ? null : testNameStrAst.Value; alreadySawName = true; } } return(new PesterSymbolReference( scriptFile, commandName.Value, testLine, testName, pesterCommandAst.Extent )); }
public override AstVisitAction VisitCommand(CommandAst commandAst) { string moduleName = string.Empty; string cmdName = commandAst.GetCommandName() ?? string.Empty; if (cmdName.IndexOf('\\') != -1) { var s = cmdName.Split('\\'); moduleName = s[0]; cmdName = s[1]; } string resolvedCmd = Helpers.ResolveAlias(cmdName) ?? cmdName; HelpEntity helpResult; if (string.IsNullOrEmpty(moduleName)) { var helpResults = HelpTableQueryRange(resolvedCmd); helpResult = helpResults?.FirstOrDefault(); if (helpResults.Count > 1) { this.errorMessage = $"The command '{helpResult?.CommandName}' is present in more than one module: '{string.Join("', '", helpResults.Select(r => r.ModuleName))}'. Explicitly prepend the module name to the command to select one: '{helpResults.First().ModuleName}\\{helpResult?.CommandName}'"; } } else { helpResult = HelpTableQuery(resolvedCmd, moduleName); if (string.IsNullOrEmpty(helpResult?.ModuleName)) { helpResult = new() { ModuleName = moduleName }; } } var description = helpResult?.Synopsis?.ToString(); if (string.IsNullOrEmpty(description)) { // Try to find out if this may be a cmdlet if (resolvedCmd.IndexOf('-') > 0) { var approvedVerbs = GetApprovedVerbs(); var possibleVerb = resolvedCmd[..resolvedCmd.IndexOf('-')];
/// <summary> /// For a command like "gci -path c:", returns the extent of "gci" in the command /// </summary> private IScriptExtent GetCommandExtent(CommandAst commandAst) { var cmdName = commandAst.GetCommandName(); foreach (var cmdElement in commandAst.CommandElements) { var stringConstExpressinAst = cmdElement as StringConstantExpressionAst; if (stringConstExpressinAst != null) { if (stringConstExpressinAst.Value.Equals(cmdName)) { return(stringConstExpressinAst.Extent); } } } return(commandAst.Extent); }
/// <summary> /// Visit CommandAst. Skip if name of command is in /// namestobeskipped /// </summary> /// <param name="commandAst"></param> /// <returns></returns> public override AstVisitAction VisitCommand(CommandAst commandAst) { if (commandAst == null || commandAst.GetCommandName() == null) { return(AstVisitAction.SkipChildren); } if (commandAst.CommandElements != null && commandAst.CommandElements.Count > 0) { var firstCommand = commandAst.CommandElements[0]; if (NamesToBeSkipped.Contains(firstCommand.Extent.Text, StringComparer.OrdinalIgnoreCase)) { return(AstVisitAction.SkipChildren); } } return(AstVisitAction.Continue); }
public override AstVisitAction VisitCommand(CommandAst commandAst) { var commandName = commandAst.GetCommandName(); if (commandName != null) { if (_singleton._engineIntrinsics != null) { var commandInfo = _singleton._engineIntrinsics.InvokeCommand.GetCommand(commandName, CommandTypes.All); if (commandInfo == null && !_singleton.UnresolvedCommandCouldSucceed(commandName, _rootAst)) { _singleton._current = commandAst.CommandElements[0].Extent.EndOffset; detectedError = string.Format(CultureInfo.CurrentCulture, PSReadLineResources.CommandNotFoundError, commandName); return(AstVisitAction.StopVisit); } } if (commandAst.CommandElements.Any(e => e is ScriptBlockExpressionAst)) { if (_singleton._options.CommandsToValidateScriptBlockArguments == null || !_singleton._options.CommandsToValidateScriptBlockArguments.Contains(commandName)) { return(AstVisitAction.SkipChildren); } } } if (_singleton._options.CommandValidationHandler != null) { try { _singleton._options.CommandValidationHandler(commandAst); } catch (Exception e) { detectedError = e.Message; } } return(!string.IsNullOrWhiteSpace(detectedError) ? AstVisitAction.StopVisit : AstVisitAction.Continue); }
public static Dictionary <string, object> FindBoundParameters(CommandAst commandAst) { var commandName = commandAst.GetCommandName(); var assembly = Assembly.GetExecutingAssembly(); var resourceName = "CodeConverter.PowerShell.GetBoundParameters.ps1"; string getBoundParameterScript; using (Stream stream = assembly.GetManifestResourceStream(resourceName)) using (StreamReader reader = new StreamReader(stream)) { getBoundParameterScript = reader.ReadToEnd(); } resourceName = $"CodeConverter.PowerShell.ProxyCommands.{commandName}.ps1"; string proxyCommand; using (Stream stream = assembly.GetManifestResourceStream(resourceName)) using (StreamReader reader = new StreamReader(stream)) { proxyCommand = reader.ReadToEnd(); } var result = new Dictionary <string, object>(); using (var powerShell = System.Management.Automation.PowerShell.Create()) { powerShell.AddScript(getBoundParameterScript); powerShell.Invoke(); powerShell.AddCommand("Get-BoundParameter"); powerShell.AddParameter("commandAst", commandAst); powerShell.AddParameter("proxyCommand", proxyCommand); var psobject = powerShell.Invoke(); foreach (var param in psobject.Select(m => m.BaseObject).Cast <Hashtable>()) { result.Add(param["Name"] as string, param["Ast"]); } } return(result); }
public override AstVisitAction VisitCommand(CommandAst commandAst) { CountOfCommands++; var commandName = commandAst.GetCommandName(); if (commandName != null) { int commandCount; CommandsCalled.TryGetValue(commandName, out commandCount); CommandsCalled[commandName] = commandCount + 1; } if (commandAst.InvocationOperator == TokenKind.Dot) { CountOfDotSourcedCommands++; } return(AstVisitAction.Continue); }