/// <summary>
        /// Adds keys in the input hashtable to the symbol reference
        /// </summary>
        public override AstVisitAction VisitHashtable(HashtableAst hashtableAst)
        {
            if (hashtableAst.KeyValuePairs == null)
            {
                return AstVisitAction.Continue;
            }

            foreach (var kvp in hashtableAst.KeyValuePairs)
            {
                if (kvp.Item1 is StringConstantExpressionAst keyStrConstExprAst)
                {
                    IScriptExtent nameExtent = new ScriptExtent()
                    {
                        Text = keyStrConstExprAst.Value,
                        StartLineNumber = kvp.Item1.Extent.StartLineNumber,
                        EndLineNumber = kvp.Item2.Extent.EndLineNumber,
                        StartColumnNumber = kvp.Item1.Extent.StartColumnNumber,
                        EndColumnNumber = kvp.Item2.Extent.EndColumnNumber,
                        File = hashtableAst.Extent.File
                    };

                    SymbolType symbolType = SymbolType.HashtableKey;

                    this.SymbolReferences.Add(
                        new SymbolReference(
                            symbolType,
                            nameExtent));

                }
            }

            return AstVisitAction.Continue;
        }
        private static List <Tuple <IScriptExtent, IScriptExtent> > GetExtents(
            TokenOperations tokenOps,
            HashtableAst hashtableAst)
        {
            var nodeTuples = new List <Tuple <IScriptExtent, IScriptExtent> >();

            foreach (var kvp in hashtableAst.KeyValuePairs)
            {
                var keyStartOffset = kvp.Item1.Extent.StartOffset;
                var keyTokenNode   = tokenOps.GetTokenNodes(
                    token => token.Extent.StartOffset == keyStartOffset).FirstOrDefault();
                if (keyTokenNode == null ||
                    keyTokenNode.Next == null ||
                    keyTokenNode.Next.Value.Kind != TokenKind.Equals)
                {
                    return(null);
                }

                nodeTuples.Add(new Tuple <IScriptExtent, IScriptExtent>(
                                   kvp.Item1.Extent,
                                   keyTokenNode.Next.Value.Extent));
            }

            return(nodeTuples);
        }
        /// <summary>
        /// Gets the correction extent
        /// </summary>
        /// <param name="ast"></param>
        /// <returns>A List of CorrectionExtent</returns>
        private List <CorrectionExtent> GetCorrectionExtent(HashtableAst ast)
        {
            int startLineNumber;
            int startColumnNumber;

            // for empty hashtable insert after after "@{"
            if (ast.KeyValuePairs.Count == 0)
            {
                // check if ast starts with "@{"
                if (ast.Extent.Text.IndexOf("@{") != 0)
                {
                    return(null);
                }
                startLineNumber   = ast.Extent.StartLineNumber;
                startColumnNumber = ast.Extent.StartColumnNumber + 2; // 2 for "@{",
            }
            else // for non-empty hashtable insert after the last element
            {
                int maxLine = 0;
                int lastCol = 0;
                foreach (var keyVal in ast.KeyValuePairs)
                {
                    if (keyVal.Item2.Extent.EndLineNumber > maxLine)
                    {
                        maxLine = keyVal.Item2.Extent.EndLineNumber;
                        lastCol = keyVal.Item2.Extent.EndColumnNumber;
                    }
                }
                startLineNumber   = maxLine;
                startColumnNumber = lastCol;
            }

            var    correctionExtents = new List <CorrectionExtent>();
            string fieldName         = "ModuleVersion";
            string fieldValue        = "1.0.0.0";
            string description       = string.Format(
                CultureInfo.CurrentCulture,
                Strings.MissingModuleManifestFieldCorrectionDescription,
                fieldName,
                fieldValue);
            var correctionTextTemplate = @"
# Version number of this module.
{0} = '{1}'
";
            var correctionText         = string.Format(
                correctionTextTemplate,
                fieldName,
                fieldValue);
            var correctionExtent = new CorrectionExtent(
                startLineNumber,
                startLineNumber,
                startColumnNumber,
                startColumnNumber,
                correctionText,
                ast.Extent.File,
                description);

            correctionExtents.Add(correctionExtent);
            return(correctionExtents);
        }
 /// <summary>
 /// Checks if the *ToExport fields are explicitly set to arrays, eg. @(...), and the array entries do not contain any wildcard.
 /// </summary>
 /// <param name="key"></param>
 /// <param name="hast"></param>
 /// <param name="scriptText"></param>
 /// <param name="extent"></param>
 /// <returns>A boolean value indicating if the the ToExport fields are explicitly set to arrays or not.</returns>
 private bool HasAcceptableExportField(string key, HashtableAst hast, string scriptText, out IScriptExtent extent)
 {
     extent = null;
     foreach (var pair in hast.KeyValuePairs)
     {
         var keyStrConstAst = pair.Item1 as StringConstantExpressionAst;
         if (keyStrConstAst != null && keyStrConstAst.Value.Equals(key, StringComparison.OrdinalIgnoreCase))
         {
             // Checks for wildcard character in the entry.
             var astWithWildcard = pair.Item2.Find(HasWildcardInExpression, false);
             if (astWithWildcard != null)
             {
                 extent = astWithWildcard.Extent;
                 return(false);
             }
             else
             {
                 // Checks for $null in the entry.
                 var astWithNull = pair.Item2.Find(HasNullInExpression, false);
                 if (astWithNull != null)
                 {
                     extent = astWithNull.Extent;
                     return(false);
                 }
                 else
                 {
                     return(true);
                 }
             }
         }
     }
     return(true);
 }
        private static List <Tuple <IScriptExtent, IScriptExtent> > GetExtents(
            TokenOperations tokenOps,
            HashtableAst hashtableAst)
        {
            var nodeTuples = new List <Tuple <IScriptExtent, IScriptExtent> >();

            foreach (var kvp in hashtableAst.KeyValuePairs)
            {
                var  keyStartOffset        = kvp.Item1.Extent.StartOffset;
                bool keyStartOffSetReached = false;
                var  keyTokenNode          = tokenOps.GetTokenNodes(
                    token =>
                {
                    if (keyStartOffSetReached)
                    {
                        return(token.Kind == TokenKind.Equals);
                    }
                    if (token.Extent.StartOffset == keyStartOffset)
                    {
                        keyStartOffSetReached = true;
                    }
                    return(false);
                }).FirstOrDefault();
                if (keyTokenNode == null || keyTokenNode.Value == null)
                {
                    continue;
                }
                var assignmentToken = keyTokenNode.Value.Extent;

                nodeTuples.Add(new Tuple <IScriptExtent, IScriptExtent>(
                                   kvp.Item1.Extent, assignmentToken));
            }

            return(nodeTuples);
        }
 public static HashtableAst Update(
     this HashtableAst ast,
     IEnumerable <Tuple <ExpressionAst, StatementAst> > keyValuePairs = null)
 {
     return(new HashtableAst(
                ast.Extent,
                keyValuePairs?.CloneAll() ?? ast.KeyValuePairs?.CloneAll()));
 }
Exemple #7
0
        public void HashTable0()
        {
            HashtableAst hashtableAst = ParseStatement("@{ }")
                                        .PipelineElements[0]
                                        .Expression;

            Assert.AreEqual(0, hashtableAst.KeyValuePairs.Count);
        }
        public object VisitHashtable(HashtableAst hashtableAst)
        {
            if (hashtableAst.KeyValuePairs.Count > MaxHashtableKeyCount)
            {
                return(false);
            }

            return(hashtableAst.KeyValuePairs.All(pair => (bool)pair.Item1.Accept(this) && (bool)pair.Item2.Accept(this)));
        }
Exemple #9
0
        public static Hashtable GetHashtable(HashtableAst ast)
        {
            if (ast != null)
            {
                return(ast.Visit(new PowerShellHashtableVisitor()) as Hashtable);
            }

            return(null);
        }
Exemple #10
0
 public virtual object VisitHashtable(HashtableAst hashtableAst)
 {
     foreach (var keyValuePair in hashtableAst.KeyValuePairs)
     {
         VisitElement(keyValuePair.Item1);
         VisitElement(keyValuePair.Item2);
     }
     return(hashtableAst);
 }
Exemple #11
0
        public object VisitHashtable(HashtableAst hashtableAst)
        {
            var result = new Hashtable(StringComparer.InvariantCultureIgnoreCase);

            foreach (var pair in hashtableAst.KeyValuePairs)
            {
                result.Add(pair.Item1.Visit(this), pair.Item2.Visit(this));
            }
            return(result);
        }
Exemple #12
0
        public void HashTableUnquotedName()
        {
            HashtableAst hashtableAst = ParseStatement("@{ a = 'b' }")
                                        .PipelineElements[0]
                                        .Expression;

            var nameAst = (StringConstantExpressionAst)hashtableAst.KeyValuePairs.Single().Item1;

            Assert.AreEqual("a", nameAst.Value);
        }
Exemple #13
0
        public void HashTableIntegerKey()
        {
            HashtableAst hashtableAst = ParseStatement("@{ 10 = 'b' }")
                                        .PipelineElements[0]
                                        .Expression;

            var nameAst = (ConstantExpressionAst)hashtableAst.KeyValuePairs.Single().Item1;

            Assert.AreEqual(10, nameAst.Value);
        }
Exemple #14
0
        public void HashTable2()
        {
            HashtableAst hashtableAst = ParseInput("@{ a = b ; c = d }")
                                        .EndBlock
                                        .Statements[0]
                                        .PipelineElements[0]
                                        .Expression;

            Assert.AreEqual(2, hashtableAst.KeyValuePairs.Count);
        }
Exemple #15
0
        public void HashTableAcceptsLineBreaksAfterEquals(string input)
        {
            // hash-entry:
            //     key-expression = new-lines_opt statement

            HashtableAst hashtableAst = ParseStatement(input)
                                        .PipelineElements[0]
                                        .Expression;

            Assert.AreEqual(1, hashtableAst.KeyValuePairs.Count);
        }
Exemple #16
0
        public void HashTableAcceptsLeadingAndTrailingLineBreaks(string input, int expectedCount)
        {
            // hash-literal-expression:
            //     @{ new-lines_opt hash-literal-body_opt new-lines_opt }

            HashtableAst hashtableAst = ParseStatement(input)
                                        .PipelineElements[0]
                                        .Expression;

            Assert.AreEqual(expectedCount, hashtableAst.KeyValuePairs.Count);
        }
        public object VisitHashtable(HashtableAst hashtableAst)
        {
            var newKeyValuePairs = new List <Tuple <ExpressionAst, StatementAst> >();

            foreach (var keyValuePair in hashtableAst.KeyValuePairs)
            {
                var newKey   = VisitElement(keyValuePair.Item1);
                var newValue = VisitElement(keyValuePair.Item2);
                newKeyValuePairs.Add(Tuple.Create(newKey, newValue));
            }
            return(new HashtableAst(hashtableAst.Extent, newKeyValuePairs));
        }
Exemple #18
0
        public override AstVisitAction VisitHashtable(HashtableAst hashtableAst)
        {
            Hashtable hashTable = new Hashtable();

            foreach (var pair in hashtableAst.KeyValuePairs)
            {
                hashTable.Add(EvaluateAst(pair.Item1), EvaluateAst(pair.Item2));
            }

            this._pipelineCommandRuntime.WriteObject(hashTable);

            return(AstVisitAction.SkipChildren);
        }
        public object VisitHashtable(HashtableAst hashtableAst)
        {
            Hashtable hashtable = new Hashtable(StringComparer.CurrentCultureIgnoreCase);

            foreach (var pair in hashtableAst.KeyValuePairs)
            {
                var key   = pair.Item1.Accept(this);
                var value = pair.Item2.Accept(this);
                hashtable.Add(key, value);
            }

            return(hashtable);
        }
Exemple #20
0
        public void HashTable2(string input, string message)
        {
            // hash-entry:
            //     key-expression = new-lines_opt statement
            // statement-terminator:
            //     ;
            //     new-line-character

            HashtableAst hashtableAst = ParseStatement(input)
                                        .PipelineElements[0]
                                        .Expression;

            Assert.AreEqual(2, hashtableAst.KeyValuePairs.Count, message);
        }
Exemple #21
0
        public void HashTable1()
        {
            HashtableAst hashtableAst = ParseStatement("@{ 'a' = 'b' }")
                                        .PipelineElements[0]
                                        .Expression;

            Assert.AreEqual(1, hashtableAst.KeyValuePairs.Count);
            dynamic keyValuePair = hashtableAst.KeyValuePairs.Single();

            StringConstantExpressionAst nameAst  = keyValuePair.Item1;
            StringConstantExpressionAst valueAst = keyValuePair.Item2.PipelineElements[0].Expression;

            Assert.AreEqual("a", nameAst.Value);
            Assert.AreEqual("b", valueAst.Value);
        }
Exemple #22
0
        public void HashTableAcceptsMultipleStatementTerminators(string input, int expectedCount)
        {
            // statement-terminators:
            //     statement-terminator
            //     statement-terminators statement-terminator
            // statement-terminator:
            //     ;
            //     new-line-character

            HashtableAst hashtableAst = ParseStatement(input)
                                        .PipelineElements[0]
                                        .Expression;

            Assert.AreEqual(expectedCount, hashtableAst.KeyValuePairs.Count);
        }
 public object VisitHashtable(HashtableAst hashtableAst)
 {
     foreach (Tuple <ExpressionAst, StatementAst> tuple in hashtableAst.KeyValuePairs)
     {
         if (!((bool)tuple.Item1.Accept(this)))
         {
             return(false);
         }
         if (!((bool)tuple.Item2.Accept(this)))
         {
             return(false);
         }
     }
     return(true);
 }
        public override AstVisitAction VisitHashtable(HashtableAst hashtableAst)
        {
            var keys       = string.Join(", ", hashtableAst.KeyValuePairs.Select(p => p.Item1.ToString()));
            var keysString = keys == null ? "" : $" This hash table has the following keys: '{keys}'";

            explanations.Add(
                new Explanation()
            {
                Description     = $"An object that holds key-value pairs, optimized for hash-searching for keys.{keysString}",
                CommandName     = "Hash table",
                HelpResult      = HelpTableQuery("about_hash_tables"),
                TextToHighlight = "@{"
            }.AddDefaults(hashtableAst, explanations));

            return(base.VisitHashtable(hashtableAst));
        }
        private bool HasKeysOnSeparateLines(HashtableAst hashtableAst)
        {
            var lines = new HashSet <int>();

            foreach (var kvp in hashtableAst.KeyValuePairs)
            {
                if (lines.Contains(kvp.Item1.Extent.StartLineNumber))
                {
                    return(false);
                }
                else
                {
                    lines.Add(kvp.Item1.Extent.StartLineNumber);
                }
            }

            return(true);
        }
Exemple #26
0
            public override object VisitHashtable(HashtableAst hashtableAst)
            {
                script_.Write("@{");

                if (hashtableAst.KeyValuePairs.Count > 0)
                {
                    var firstPair = hashtableAst.KeyValuePairs.First();
                    VisitElement(firstPair.Item1);
                    script_.Write("=");
                    VisitElement(firstPair.Item2);

                    foreach (var keyValuePair in hashtableAst.KeyValuePairs.Skip(1))
                    {
                        script_.Write(";");
                        VisitElement(keyValuePair.Item1);
                        script_.Write("=");
                        VisitElement(keyValuePair.Item2);
                    }
                }
                script_.Write("}");
                return(hashtableAst);
            }
        private void parseSettingsFile(string settingsFilePath)
        {
            Token[]           parserTokens  = null;
            ParseError[]      parserErrors  = null;
            Ast               profileAst    = Parser.ParseFile(settingsFilePath, out parserTokens, out parserErrors);
            IEnumerable <Ast> hashTableAsts = profileAst.FindAll(item => item is HashtableAst, false);

            // no hashtable, raise warning
            if (hashTableAsts.Count() == 0)
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.InvalidProfile, settingsFilePath));
            }

            HashtableAst hashTableAst = hashTableAsts.First() as HashtableAst;
            Hashtable    hashtable;

            try
            {
                // ideally we should use HashtableAst.SafeGetValue() but since
                // it is not available on PSv3, we resort to our own narrow implementation.
                hashtable = GetHashtableFromHashTableAst(hashTableAst);
            }
            catch (InvalidOperationException e)
            {
                throw new ArgumentException(Strings.InvalidProfile, e);
            }

            if (hashtable == null)
            {
                throw new ArgumentException(
                          String.Format(
                              CultureInfo.CurrentCulture,
                              Strings.InvalidProfile,
                              settingsFilePath));
            }

            parseSettingsHashtable(hashtable);
        }
Exemple #28
0
        /// <summary>
        /// Create a hashtable value from a PowerShell AST representing one,
        /// provided that the PowerShell expression is statically evaluable and safe.
        /// </summary>
        /// <param name="hashtableAst">The PowerShell representation of the hashtable value.</param>
        /// <returns>The Hashtable as a hydrated .NET value.</returns>
        private static Hashtable GetSafeValueFromHashtableAst(HashtableAst hashtableAst)
        {
            if (hashtableAst == null)
            {
                throw new ArgumentNullException(nameof(hashtableAst));
            }

            if (hashtableAst.KeyValuePairs == null)
            {
                throw CreateInvalidDataExceptionFromAst(hashtableAst);
            }

            var hashtable = new Hashtable();

            foreach (Tuple <ExpressionAst, StatementAst> entry in hashtableAst.KeyValuePairs)
            {
                // Get the key
                object key = GetSafeValueFromExpressionAst(entry.Item1);
                if (key == null)
                {
                    throw CreateInvalidDataExceptionFromAst(entry.Item1);
                }

                // Get the value
                ExpressionAst valueExprAst = (entry.Item2 as PipelineAst)?.GetPureExpression();
                if (valueExprAst == null)
                {
                    throw CreateInvalidDataExceptionFromAst(entry.Item2);
                }

                // Add the key/value entry into the hydrated hashtable
                hashtable[key] = GetSafeValueFromExpressionAst(valueExprAst);
            }

            return(hashtable);
        }
        internal List <CompletionResult> GetResultHelper(CompletionContext completionContext, out int replacementIndex, out int replacementLength, bool isQuotedString)
        {
            replacementIndex  = -1;
            replacementLength = -1;
            Token tokenAtCursor          = completionContext.TokenAtCursor;
            Ast   lastAst                = completionContext.RelatedAsts.Last <Ast>();
            List <CompletionResult> list = null;

            if (tokenAtCursor == null)
            {
                if (!isQuotedString && (((((lastAst is CommandParameterAst) || (lastAst is CommandAst)) || ((lastAst is ExpressionAst) && (lastAst.Parent is CommandAst))) || ((lastAst is ExpressionAst) && (lastAst.Parent is CommandParameterAst))) || (((lastAst is ExpressionAst) && (lastAst.Parent is ArrayLiteralAst)) && ((lastAst.Parent.Parent is CommandAst) || (lastAst.Parent.Parent is CommandParameterAst)))))
                {
                    completionContext.WordToComplete = string.Empty;
                    HashtableAst hashtableAst = lastAst as HashtableAst;
                    if (hashtableAst != null)
                    {
                        completionContext.ReplacementIndex  = replacementIndex = completionContext.CursorPosition.Offset;
                        completionContext.ReplacementLength = replacementLength = 0;
                        list = CompletionCompleters.CompleteHashtableKey(completionContext, hashtableAst);
                    }
                    else
                    {
                        list              = CompletionCompleters.CompleteCommandArgument(completionContext);
                        replacementIndex  = completionContext.ReplacementIndex;
                        replacementLength = completionContext.ReplacementLength;
                    }
                }
                else if (!isQuotedString)
                {
                    bool flag = false;
                    if ((lastAst is ErrorExpressionAst) && (lastAst.Parent is FileRedirectionAst))
                    {
                        flag = true;
                    }
                    else if ((lastAst is ErrorStatementAst) && CompleteAgainstSwitchFile(lastAst, completionContext.TokenBeforeCursor))
                    {
                        flag = true;
                    }
                    if (flag)
                    {
                        completionContext.WordToComplete = string.Empty;
                        list              = new List <CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
                        replacementIndex  = completionContext.ReplacementIndex;
                        replacementLength = completionContext.ReplacementLength;
                    }
                }
            }
            else
            {
                TokenKind kind;
                replacementIndex  = tokenAtCursor.Extent.StartScriptPosition.Offset;
                replacementLength = tokenAtCursor.Extent.EndScriptPosition.Offset - replacementIndex;
                completionContext.ReplacementIndex  = replacementIndex;
                completionContext.ReplacementLength = replacementLength;
                switch (tokenAtCursor.Kind)
                {
                case TokenKind.ColonColon:
                case TokenKind.Dot:
                    replacementIndex += tokenAtCursor.Text.Length;
                    replacementLength = 0;
                    list = CompletionCompleters.CompleteMember(completionContext, tokenAtCursor.Kind == TokenKind.ColonColon);
                    goto Label_05DC;

                case TokenKind.Multiply:
                case TokenKind.Identifier:
                case TokenKind.Generic:
                    list = this.GetResultForIdentifier(completionContext, ref replacementIndex, ref replacementLength, isQuotedString);
                    goto Label_05DC;

                case TokenKind.Minus:
                    if (CompleteOperator(tokenAtCursor, lastAst))
                    {
                        list = CompletionCompleters.CompleteOperator("");
                    }
                    else if (CompleteAgainstStatementFlags(completionContext.RelatedAsts[0], null, tokenAtCursor, out kind))
                    {
                        completionContext.WordToComplete = tokenAtCursor.Text;
                        list = CompletionCompleters.CompleteStatementFlags(kind, completionContext.WordToComplete);
                    }
                    goto Label_05DC;

                case TokenKind.Redirection:
                    if ((lastAst is ErrorExpressionAst) && (lastAst.Parent is FileRedirectionAst))
                    {
                        completionContext.WordToComplete    = string.Empty;
                        completionContext.ReplacementIndex  = replacementIndex += tokenAtCursor.Text.Length;
                        completionContext.ReplacementLength = replacementLength = 0;
                        list = new List <CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
                    }
                    goto Label_05DC;

                case TokenKind.Variable:
                case TokenKind.SplattedVariable:
                    completionContext.WordToComplete = ((VariableToken)tokenAtCursor).VariablePath.UserPath;
                    list = CompletionCompleters.CompleteVariable(completionContext);
                    goto Label_05DC;

                case TokenKind.Parameter:
                    if (!isQuotedString)
                    {
                        completionContext.WordToComplete = tokenAtCursor.Text;
                        CommandAst parent = lastAst.Parent as CommandAst;
                        if ((!(lastAst is StringConstantExpressionAst) || (parent == null)) || (parent.CommandElements.Count != 1))
                        {
                            if (CompleteAgainstStatementFlags(null, lastAst, null, out kind))
                            {
                                list = CompletionCompleters.CompleteStatementFlags(kind, completionContext.WordToComplete);
                            }
                            else if (CompleteOperator(tokenAtCursor, lastAst))
                            {
                                list = CompletionCompleters.CompleteOperator(completionContext.WordToComplete);
                            }
                            else if (completionContext.WordToComplete.EndsWith(":", StringComparison.Ordinal))
                            {
                                replacementIndex  = tokenAtCursor.Extent.EndScriptPosition.Offset;
                                replacementLength = 0;
                                completionContext.WordToComplete = string.Empty;
                                list = CompletionCompleters.CompleteCommandArgument(completionContext);
                            }
                            else
                            {
                                list = CompletionCompleters.CompleteCommandParameter(completionContext);
                            }
                        }
                        else
                        {
                            list = CompleteFileNameAsCommand(completionContext);
                        }
                    }
                    goto Label_05DC;

                case TokenKind.Number:
                    if ((lastAst is ConstantExpressionAst) && (((lastAst.Parent is CommandAst) || (lastAst.Parent is CommandParameterAst)) || ((lastAst.Parent is ArrayLiteralAst) && ((lastAst.Parent.Parent is CommandAst) || (lastAst.Parent.Parent is CommandParameterAst)))))
                    {
                        completionContext.WordToComplete = tokenAtCursor.Text;
                        list              = CompletionCompleters.CompleteCommandArgument(completionContext);
                        replacementIndex  = completionContext.ReplacementIndex;
                        replacementLength = completionContext.ReplacementLength;
                    }
                    goto Label_05DC;

                case TokenKind.Comment:
                    if (!isQuotedString)
                    {
                        completionContext.WordToComplete = tokenAtCursor.Text;
                        list = CompletionCompleters.CompleteComment(completionContext);
                    }
                    goto Label_05DC;

                case TokenKind.StringLiteral:
                case TokenKind.StringExpandable:
                    list = this.GetResultForString(completionContext, ref replacementIndex, ref replacementLength, isQuotedString);
                    goto Label_05DC;

                case TokenKind.RBracket:
                    if (lastAst is TypeExpressionAst)
                    {
                        TypeExpressionAst       targetExpr = (TypeExpressionAst)lastAst;
                        List <CompletionResult> results    = new List <CompletionResult>();
                        CompletionCompleters.CompleteMemberHelper(true, "*", targetExpr, completionContext, results);
                        if (results.Count > 0)
                        {
                            replacementIndex++;
                            replacementLength = 0;
                            list = (from entry in results
                                    let completionText = TokenKind.ColonColon.Text() + entry.CompletionText
                                                         select new CompletionResult(completionText, entry.ListItemText, entry.ResultType, entry.ToolTip)).ToList <CompletionResult>();
                        }
                    }
                    goto Label_05DC;

                case TokenKind.Comma:
                    if ((lastAst is ErrorExpressionAst) && ((lastAst.Parent is CommandAst) || (lastAst.Parent is CommandParameterAst)))
                    {
                        replacementIndex += replacementLength;
                        replacementLength = 0;
                        list = CompletionCompleters.CompleteCommandArgument(completionContext);
                    }
                    goto Label_05DC;
                }
                if ((tokenAtCursor.TokenFlags & TokenFlags.Keyword) != TokenFlags.None)
                {
                    completionContext.WordToComplete = tokenAtCursor.Text;
                    list = CompleteFileNameAsCommand(completionContext);
                    List <CompletionResult> collection = CompletionCompleters.CompleteCommand(completionContext);
                    if ((collection != null) && (collection.Count > 0))
                    {
                        list.AddRange(collection);
                    }
                }
                else
                {
                    replacementIndex  = -1;
                    replacementLength = -1;
                }
            }
Label_05DC:
            if ((list == null) || (list.Count == 0))
            {
                TypeExpressionAst ast5 = completionContext.RelatedAsts.OfType <TypeExpressionAst>().FirstOrDefault <TypeExpressionAst>();
                TypeName          name = null;
                if (ast5 != null)
                {
                    name = FindTypeNameToComplete(ast5.TypeName, this._cursorPosition);
                }
                else
                {
                    TypeConstraintAst ast6 = completionContext.RelatedAsts.OfType <TypeConstraintAst>().FirstOrDefault <TypeConstraintAst>();
                    if (ast6 != null)
                    {
                        name = FindTypeNameToComplete(ast6.TypeName, this._cursorPosition);
                    }
                }
                if (name != null)
                {
                    replacementIndex  = name.Extent.StartOffset;
                    replacementLength = name.Extent.EndOffset - replacementIndex;
                    completionContext.WordToComplete = name.FullName;
                    list = CompletionCompleters.CompleteType(completionContext, "", "");
                }
            }
            if ((list == null) || (list.Count == 0))
            {
                HashtableAst ast7 = lastAst as HashtableAst;
                if (ast7 != null)
                {
                    completionContext.ReplacementIndex  = replacementIndex = completionContext.CursorPosition.Offset;
                    completionContext.ReplacementLength = replacementLength = 0;
                    list = CompletionCompleters.CompleteHashtableKey(completionContext, ast7);
                }
            }
            if ((list == null) || (list.Count == 0))
            {
                string text = completionContext.RelatedAsts[0].Extent.Text;
                if ((Regex.IsMatch(text, @"^[\S]+$") && (completionContext.RelatedAsts.Count > 0)) && (completionContext.RelatedAsts[0] is ScriptBlockAst))
                {
                    replacementIndex  = completionContext.RelatedAsts[0].Extent.StartScriptPosition.Offset;
                    replacementLength = completionContext.RelatedAsts[0].Extent.EndScriptPosition.Offset - replacementIndex;
                    completionContext.WordToComplete = text;
                    list = CompleteFileNameAsCommand(completionContext);
                }
            }
            return(list);
        }
        private Hashtable GetHashtableFromHashTableAst(HashtableAst hashTableAst)
        {
            var output = new Hashtable();

            foreach (var kvp in hashTableAst.KeyValuePairs)
            {
                var keyAst = kvp.Item1 as StringConstantExpressionAst;
                if (keyAst == null)
                {
                    // first item (the key) should be a string
                    ThrowInvalidDataException(kvp.Item1);
                }
                var key = keyAst.Value;

                // parse the item2 as array
                PipelineAst   pipeAst = kvp.Item2 as PipelineAst;
                List <string> rhsList = new List <string>();
                if (pipeAst != null)
                {
                    ExpressionAst pureExp      = pipeAst.GetPureExpression();
                    var           constExprAst = pureExp as ConstantExpressionAst;
                    if (constExprAst != null)
                    {
                        var strConstExprAst = constExprAst as StringConstantExpressionAst;
                        if (strConstExprAst != null)
                        {
                            // it is a string literal
                            output[key] = strConstExprAst.Value;
                        }
                        else
                        {
                            // it is either an integer or a float
                            output[key] = constExprAst.Value;
                        }
                        continue;
                    }
                    else if (pureExp is HashtableAst)
                    {
                        output[key] = GetHashtableFromHashTableAst((HashtableAst)pureExp);
                        continue;
                    }
                    else if (pureExp is VariableExpressionAst)
                    {
                        var varExprAst = (VariableExpressionAst)pureExp;
                        switch (varExprAst.VariablePath.UserPath.ToLower())
                        {
                        case "true":
                            output[key] = true;
                            break;

                        case "false":
                            output[key] = false;
                            break;

                        default:
                            ThrowInvalidDataException(varExprAst.Extent);
                            break;
                        }

                        continue;
                    }
                    else
                    {
                        rhsList = GetArrayFromAst(pureExp);
                    }
                }

                output[key] = rhsList.ToArray();
            }

            return(output);
        }