/// <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)
 {
     return(ast is CommandAst commandAst &&
            commandAst.InvocationOperator != TokenKind.Dot &&
            PesterSymbolReference.GetCommandType(commandAst.GetCommandName()).HasValue&&
            commandAst.CommandElements.Count >= 2);
 }
        /// <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
                       ));
        }