예제 #1
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     TypeConstraintAst iteratorVariable0 = this.Attributes.OfType<TypeConstraintAst>().FirstOrDefault<TypeConstraintAst>();
     if (iteratorVariable0 != null)
     {
         Type reflectionType = iteratorVariable0.TypeName.GetReflectionType();
         if (reflectionType != null)
         {
             yield return new PSTypeName(reflectionType);
         }
         else
         {
             yield return new PSTypeName(iteratorVariable0.TypeName.FullName);
         }
     }
     IEnumerator<AttributeAst> enumerator = this.Attributes.OfType<AttributeAst>().GetEnumerator();
     while (enumerator.MoveNext())
     {
         AttributeAst current = enumerator.Current;
         PSTypeNameAttribute attribute = null;
         try
         {
             attribute = current.GetAttribute() as PSTypeNameAttribute;
         }
         catch (RuntimeException)
         {
         }
         if (attribute != null)
         {
             yield return new PSTypeName(attribute.PSTypeName);
         }
     }
 }
예제 #2
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     if ((this.TokenKind != System.Management.Automation.Language.TokenKind.Not) && (this.TokenKind != System.Management.Automation.Language.TokenKind.Exclaim))
     {
         return this.Child.GetInferredType(context);
     }
     return BinaryExpressionAst.BoolTypeNameArray;
 }
예제 #3
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     if (this.Value == null)
     {
         yield break;
     }
     yield return new PSTypeName(this.Value.GetType());
 }
예제 #4
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     System.Type reflectionType = this.Type.TypeName.GetReflectionType();
     if (reflectionType == null)
     {
         yield return new PSTypeName(this.Type.TypeName.FullName);
     }
     else
     {
         yield return new PSTypeName(reflectionType);
     }
 }
예제 #5
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     switch (this.Operator)
     {
         case TokenKind.And:
         case TokenKind.Or:
         case TokenKind.Xor:
         case TokenKind.Is:
             return BoolTypeNameArray;
     }
     return this.Left.GetInferredType(context);
 }
예제 #6
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     foreach (PSTypeName iteratorVariable0 in from clause in this.Clauses select clause.Item2.GetInferredType(context))
     {
         yield return iteratorVariable0;
     }
     if (this.ElseClause != null)
     {
         foreach (PSTypeName iteratorVariable1 in this.ElseClause.GetInferredType(context))
         {
             yield return iteratorVariable1;
         }
     }
 }
예제 #7
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     foreach (PSTypeName iteratorVariable0 in this.Body.GetInferredType(context))
     {
         yield return iteratorVariable0;
     }
     foreach (PSTypeName iteratorVariable1 in from clause in this.CatchClauses select clause.Body.GetInferredType(context))
     {
         yield return iteratorVariable1;
     }
     if (this.Finally != null)
     {
         foreach (PSTypeName iteratorVariable2 in this.Finally.GetInferredType(context))
         {
             yield return iteratorVariable2;
         }
     }
 }
예제 #8
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     IEnumerable<PSTypeName> inferredType = this.Target.GetInferredType(context);
     foreach (PSTypeName iteratorVariable1 in inferredType)
     {
         Type type = iteratorVariable1.Type;
         if (type != null)
         {
             Func<MethodInfo, bool> predicate = null;
             if (type.IsArray)
             {
                 yield return new PSTypeName(type.GetElementType());
                 continue;
             }
             foreach (Type iteratorVariable3 in type.GetInterfaces())
             {
                 if (iteratorVariable3.IsGenericType && (iteratorVariable3.GetGenericTypeDefinition() == typeof(IDictionary<,>)))
                 {
                     Type iteratorVariable4 = iteratorVariable3.GetGenericArguments()[1];
                     if (!iteratorVariable4.ContainsGenericParameters)
                     {
                         yield return new PSTypeName(iteratorVariable4);
                     }
                 }
             }
             DefaultMemberAttribute defaultMember = type.GetCustomAttributes<DefaultMemberAttribute>(true).FirstOrDefault<DefaultMemberAttribute>();
             if (defaultMember != null)
             {
                 if (predicate == null)
                 {
                     predicate = m => m.Name.Equals("get_" + defaultMember.MemberName);
                 }
                 IEnumerable<MethodInfo> iteratorVariable5 = type.GetMethods(BindingFlags.Public | BindingFlags.Instance).Where<MethodInfo>(predicate);
                 foreach (MethodInfo iteratorVariable6 in iteratorVariable5)
                 {
                     yield return new PSTypeName(iteratorVariable6.ReturnType);
                 }
             }
         }
         yield return iteratorVariable1;
     }
 }
예제 #9
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     if (this.BeginBlock != null)
     {
         foreach (PSTypeName iteratorVariable0 in this.BeginBlock.GetInferredType(context))
         {
             yield return iteratorVariable0;
         }
     }
     if (this.ProcessBlock != null)
     {
         foreach (PSTypeName iteratorVariable1 in this.ProcessBlock.GetInferredType(context))
         {
             yield return iteratorVariable1;
         }
     }
     if (this.EndBlock != null)
     {
         foreach (PSTypeName iteratorVariable2 in this.EndBlock.GetInferredType(context))
         {
             yield return iteratorVariable2;
         }
     }
 }
예제 #10
0
파일: CommandAst.cs 프로젝트: nickchal/pash
 private IEnumerable<PSTypeName> GetInferredTypeFromScriptBlockParameter(AstParameterArgumentPair argument, CompletionContext context)
 {
     AstPair iteratorVariable0 = argument as AstPair;
     if ((iteratorVariable0 != null) && (iteratorVariable0.Argument is ScriptBlockExpressionAst))
     {
         ScriptBlockExpressionAst iteratorVariable1 = (ScriptBlockExpressionAst) iteratorVariable0.Argument;
         foreach (PSTypeName iteratorVariable2 in iteratorVariable1.ScriptBlock.GetInferredType(context))
         {
             yield return iteratorVariable2;
         }
     }
 }
예제 #11
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     return this.NestedAst.SelectMany(x => x.GetInferredType(context));
 }
예제 #12
0
 private List<CompletionResult> GetResultForString(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength, bool isQuotedString)
 {
     if (isQuotedString)
     {
         return null;
     }
     Token tokenAtCursor = completionContext.TokenAtCursor;
     Ast ast = completionContext.RelatedAsts.Last<Ast>();
     List<CompletionResult> list = null;
     ExpandableStringExpressionAst ast2 = ast as ExpandableStringExpressionAst;
     StringConstantExpressionAst ast3 = ast as StringConstantExpressionAst;
     if ((ast3 != null) || (ast2 != null))
     {
         string input = (ast3 != null) ? ast3.Value : ast2.Value;
         StringConstantType type = (ast3 != null) ? ast3.StringConstantType : ast2.StringConstantType;
         string str2 = null;
         if (type == StringConstantType.DoubleQuoted)
         {
             Match match = Regex.Match(input, @"(\$[\w\d]+\.[\w\d\*]*)$");
             if (match.Success)
             {
                 str2 = match.Groups[1].Value;
             }
             else if ((match = Regex.Match(input, @"(\[[\w\d\.]+\]::[\w\d\*]*)$")).Success)
             {
                 str2 = match.Groups[1].Value;
             }
         }
         if (str2 != null)
         {
             int num3;
             int num4;
             int offset = tokenAtCursor.Extent.StartScriptPosition.Offset;
             int length = (this._cursorPosition.Offset - offset) - 1;
             if (length >= input.Length)
             {
                 length = input.Length;
             }
             CompletionAnalysis analysis = new CompletionAnalysis(this._ast, this._tokens, this._cursorPosition, this._options);
             CompletionContext context = analysis.CreateCompletionContext(completionContext.ExecutionContext);
             context.Helper = completionContext.Helper;
             List<CompletionResult> list2 = analysis.GetResultHelper(context, out num3, out num4, true);
             if ((list2 != null) && (list2.Count > 0))
             {
                 list = new List<CompletionResult>();
                 replacementIndex = (offset + 1) + (length - str2.Length);
                 replacementLength = str2.Length;
                 string str3 = str2.Substring(0, num3);
                 foreach (CompletionResult result in list2)
                 {
                     string completionText = str3 + result.CompletionText;
                     if (result.ResultType.Equals(CompletionResultType.Property))
                     {
                         completionText = TokenKind.DollarParen.Text() + completionText + TokenKind.RParen.Text();
                     }
                     else if (result.ResultType.Equals(CompletionResultType.Method))
                     {
                         completionText = TokenKind.DollarParen.Text() + completionText;
                     }
                     completionText = completionText + "\"";
                     list.Add(new CompletionResult(completionText, result.ListItemText, result.ResultType, result.ToolTip));
                 }
             }
             return list;
         }
         CommandElementAst stringAst = ast as CommandElementAst;
         string str5 = CompletionCompleters.ConcatenateStringPathArguments(stringAst, string.Empty, completionContext);
         if (str5 == null)
         {
             return list;
         }
         completionContext.WordToComplete = str5;
         if ((ast.Parent is CommandAst) || (ast.Parent is CommandParameterAst))
         {
             list = CompletionCompleters.CompleteCommandArgument(completionContext);
             replacementIndex = completionContext.ReplacementIndex;
             replacementLength = completionContext.ReplacementLength;
             return list;
         }
         list = new List<CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
         if (str5.IndexOf('-') != -1)
         {
             List<CompletionResult> collection = CompletionCompleters.CompleteCommand(completionContext);
             if ((collection != null) && (collection.Count > 0))
             {
                 list.AddRange(collection);
             }
         }
     }
     return list;
 }
예제 #13
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     yield return new PSTypeName(typeof(object[]));
 }
예제 #14
0
        private List<CompletionResult> GetResultForString(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength, bool isQuotedString)
        {
            // When it's the content of a quoted string, we only handle variable/member completion
            if (isQuotedString) { return null; }
            var tokenAtCursor = completionContext.TokenAtCursor;
            var lastAst = completionContext.RelatedAsts.Last();

            List<CompletionResult> result = null;
            var expandableString = lastAst as ExpandableStringExpressionAst;
            var constantString = lastAst as StringConstantExpressionAst;
            if (constantString == null && expandableString == null) { return null; }

            string strValue = constantString != null ? constantString.Value : expandableString.Value;
            StringConstantType strType = constantString != null ? constantString.StringConstantType : expandableString.StringConstantType;
            string subInput = null;

            bool shouldContinue;
            result = GetResultForEnumPropertyValueOfDSCResource(completionContext, strValue, ref replacementIndex, ref replacementLength, out shouldContinue);
            if (!shouldContinue || (result != null && result.Count > 0))
            {
                return result;
            }

            if (strType == StringConstantType.DoubleQuoted)
            {
                var match = Regex.Match(strValue, @"(\$[\w\d]+\.[\w\d\*]*)$");
                if (match.Success)
                {
                    subInput = match.Groups[1].Value;
                }
                else if ((match = Regex.Match(strValue, @"(\[[\w\d\.]+\]::[\w\d\*]*)$")).Success)
                {
                    subInput = match.Groups[1].Value;
                }
            }

            // Handle variable/member completion
            if (subInput != null)
            {
                int stringStartIndex = tokenAtCursor.Extent.StartScriptPosition.Offset;
                int cursorIndexInString = _cursorPosition.Offset - stringStartIndex - 1;
                if (cursorIndexInString >= strValue.Length)
                    cursorIndexInString = strValue.Length;

                var analysis = new CompletionAnalysis(_ast, _tokens, _cursorPosition, _options);
                var subContext = analysis.CreateCompletionContext(completionContext.ExecutionContext);
                subContext.Helper = completionContext.Helper;

                int subReplaceIndex, subReplaceLength;
                var subResult = analysis.GetResultHelper(subContext, out subReplaceIndex, out subReplaceLength, true);

                if (subResult != null && subResult.Count > 0)
                {
                    result = new List<CompletionResult>();
                    replacementIndex = stringStartIndex + 1 + (cursorIndexInString - subInput.Length);
                    replacementLength = subInput.Length;
                    string prefix = subInput.Substring(0, subReplaceIndex);

                    foreach (CompletionResult entry in subResult)
                    {
                        string completionText = prefix + entry.CompletionText;
                        if (entry.ResultType == CompletionResultType.Property)
                        {
                            completionText = TokenKind.DollarParen.Text() + completionText + TokenKind.RParen.Text();
                        }
                        else if (entry.ResultType == CompletionResultType.Method)
                        {
                            completionText = TokenKind.DollarParen.Text() + completionText;
                        }

                        completionText += "\"";
                        result.Add(new CompletionResult(completionText, entry.ListItemText, entry.ResultType, entry.ToolTip));
                    }
                }
            }
            else
            {
                var commandElementAst = lastAst as CommandElementAst;
                string wordToComplete =
                    CompletionCompleters.ConcatenateStringPathArguments(commandElementAst, string.Empty, completionContext);

                if (wordToComplete != null)
                {
                    completionContext.WordToComplete = wordToComplete;

                    // Handle scenarios like this: cd 'c:\windows\win'<tab>
                    if (lastAst.Parent is CommandAst || lastAst.Parent is CommandParameterAst)
                    {
                        result = CompletionCompleters.CompleteCommandArgument(completionContext);
                        replacementIndex = completionContext.ReplacementIndex;
                        replacementLength = completionContext.ReplacementLength;
                    }
                    // Hanlde scenarios like this: "c:\wind"<tab>. Treat the StringLiteral/StringExpandable as path/command
                    else
                    {
                        // Handle path/commandname completion for quoted string
                        result = new List<CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));

                        // Try command name completion only if the text contains '-'
                        if (wordToComplete.IndexOf('-') != -1)
                        {
                            var commandNameResult = CompletionCompleters.CompleteCommand(completionContext);
                            if (commandNameResult != null && commandNameResult.Count > 0)
                            {
                                result.AddRange(commandNameResult);
                            }
                        }
                    }
                }
            }

            return result;
        }
예제 #15
0
        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);
        }
예제 #16
0
        private List <CompletionResult> GetResultForIdentifier(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength, bool isQuotedString)
        {
            Token tokenAtCursor            = completionContext.TokenAtCursor;
            Ast   lastAst                  = completionContext.RelatedAsts.Last <Ast>();
            List <CompletionResult> source = null;

            completionContext.WordToComplete = tokenAtCursor.Text;
            StringConstantExpressionAst ast2 = lastAst as StringConstantExpressionAst;

            if ((ast2 != null) && ast2.Value.Equals("$", StringComparison.Ordinal))
            {
                completionContext.WordToComplete = "";
                return(CompletionCompleters.CompleteVariable(completionContext));
            }
            if ((tokenAtCursor.TokenFlags & TokenFlags.CommandName) != TokenFlags.None)
            {
                if ((completionContext.RelatedAsts.Count > 0) && (completionContext.RelatedAsts[0] is ScriptBlockAst))
                {
                    Ast lastAstAtCursor             = null;
                    InternalScriptPosition position = (InternalScriptPosition)this._cursorPosition;
                    int offset = position.Offset - tokenAtCursor.Text.Length;
                    if (offset >= 0)
                    {
                        InternalScriptPosition cursorPosition = position.CloneWithNewOffset(offset);
                        ScriptBlockAst         scriptBlockAst = (ScriptBlockAst)completionContext.RelatedAsts[0];
                        lastAstAtCursor = GetLastAstAtCursor(scriptBlockAst, cursorPosition);
                    }
                    if (((lastAstAtCursor != null) && (lastAstAtCursor.Extent.EndLineNumber == tokenAtCursor.Extent.StartLineNumber)) && (lastAstAtCursor.Extent.EndColumnNumber == tokenAtCursor.Extent.StartColumnNumber))
                    {
                        if (tokenAtCursor.Text.IndexOfAny(new char[] { '\\', '/' }) == 0)
                        {
                            string str = CompletionCompleters.ConcatenateStringPathArguments(lastAstAtCursor as CommandElementAst, tokenAtCursor.Text, completionContext);
                            if (str != null)
                            {
                                completionContext.WordToComplete = str;
                                source = new List <CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
                                if (source.Count > 0)
                                {
                                    replacementIndex   = lastAstAtCursor.Extent.StartScriptPosition.Offset;
                                    replacementLength += lastAstAtCursor.Extent.Text.Length;
                                }
                                return(source);
                            }
                            VariableExpressionAst variableAst = lastAstAtCursor as VariableExpressionAst;
                            string str2 = (variableAst != null) ? CompletionCompleters.CombineVariableWithPartialPath(variableAst, tokenAtCursor.Text, completionContext.ExecutionContext) : null;
                            if (str2 == null)
                            {
                                return(source);
                            }
                            completionContext.WordToComplete = str2;
                            replacementIndex   = lastAstAtCursor.Extent.StartScriptPosition.Offset;
                            replacementLength += lastAstAtCursor.Extent.Text.Length;
                            completionContext.ReplacementIndex  = replacementIndex;
                            completionContext.ReplacementLength = replacementLength;
                        }
                        else if (!(lastAstAtCursor is ErrorExpressionAst) || !(lastAstAtCursor.Parent is IndexExpressionAst))
                        {
                            return(source);
                        }
                    }
                }
                if (!isQuotedString)
                {
                    StringExpandableToken token2 = tokenAtCursor as StringExpandableToken;
                    if (((token2 != null) && (token2.NestedTokens != null)) && (ast2 != null))
                    {
                        try
                        {
                            string expandedString = null;
                            ExpandableStringExpressionAst expandableStringAst = new ExpandableStringExpressionAst(ast2.Extent, ast2.Value, StringConstantType.BareWord);
                            if (CompletionCompleters.IsPathSafelyExpandable(expandableStringAst, string.Empty, completionContext.ExecutionContext, out expandedString))
                            {
                                completionContext.WordToComplete = expandedString;
                            }
                            else
                            {
                                return(source);
                            }
                        }
                        catch (Exception exception)
                        {
                            CommandProcessorBase.CheckForSevereException(exception);
                            return(source);
                        }
                    }
                    source = CompleteFileNameAsCommand(completionContext);
                    List <CompletionResult> collection = CompletionCompleters.CompleteCommand(completionContext);
                    if ((collection != null) && (collection.Count > 0))
                    {
                        source.AddRange(collection);
                    }
                }
                return(source);
            }
            if (((tokenAtCursor.Text.Length == 1) && tokenAtCursor.Text[0].IsDash()) && (lastAst.Parent is CommandAst))
            {
                if (isQuotedString)
                {
                    return(source);
                }
                return(CompletionCompleters.CompleteCommandParameter(completionContext));
            }
            TokenKind unknown = TokenKind.Unknown;
            bool      flag    = lastAst.Parent is MemberExpressionAst;
            bool      @static = flag ? ((MemberExpressionAst)lastAst.Parent).Static : false;
            bool      flag3   = false;

            if (!flag)
            {
                if (tokenAtCursor.Text.Equals(TokenKind.Dot.Text(), StringComparison.Ordinal))
                {
                    unknown = TokenKind.Dot;
                    flag    = true;
                }
                else if (tokenAtCursor.Text.Equals(TokenKind.ColonColon.Text(), StringComparison.Ordinal))
                {
                    unknown = TokenKind.ColonColon;
                    flag    = true;
                }
                else if (tokenAtCursor.Kind.Equals(TokenKind.Multiply) && (lastAst is BinaryExpressionAst))
                {
                    BinaryExpressionAst item          = (BinaryExpressionAst)lastAst;
                    MemberExpressionAst left          = item.Left as MemberExpressionAst;
                    IScriptExtent       errorPosition = item.ErrorPosition;
                    if (((left != null) && (item.Operator == TokenKind.Multiply)) && (errorPosition.StartOffset == left.Member.Extent.EndOffset))
                    {
                        @static = left.Static;
                        unknown = @static ? TokenKind.ColonColon : TokenKind.Dot;
                        flag    = true;
                        flag3   = true;
                        completionContext.RelatedAsts.Remove(item);
                        completionContext.RelatedAsts.Add(left);
                        StringConstantExpressionAst member = left.Member as StringConstantExpressionAst;
                        if (member != null)
                        {
                            replacementIndex   = member.Extent.StartScriptPosition.Offset;
                            replacementLength += member.Extent.Text.Length;
                        }
                    }
                }
            }
            if (flag)
            {
                source = CompletionCompleters.CompleteMember(completionContext, @static || (unknown == TokenKind.ColonColon));
                if (source.Any <CompletionResult>())
                {
                    if (!flag3 && (unknown != TokenKind.Unknown))
                    {
                        replacementIndex += tokenAtCursor.Text.Length;
                        replacementLength = 0;
                    }
                    return(source);
                }
            }
            if (lastAst.Parent is HashtableAst)
            {
                source = CompletionCompleters.CompleteHashtableKey(completionContext, (HashtableAst)lastAst.Parent);
                if ((source != null) && source.Any <CompletionResult>())
                {
                    return(source);
                }
            }
            if (!isQuotedString)
            {
                bool flag4 = false;
                if ((lastAst.Parent is FileRedirectionAst) || CompleteAgainstSwitchFile(lastAst, completionContext.TokenBeforeCursor))
                {
                    string str4 = CompletionCompleters.ConcatenateStringPathArguments(lastAst as CommandElementAst, string.Empty, completionContext);
                    if (str4 != null)
                    {
                        flag4 = true;
                        completionContext.WordToComplete = str4;
                    }
                }
                else if (tokenAtCursor.Text.IndexOfAny(new char[] { '\\', '/' }) == 0)
                {
                    CommandBaseAst parent = lastAst.Parent as CommandBaseAst;
                    if ((parent != null) && parent.Redirections.Any <RedirectionAst>())
                    {
                        FileRedirectionAst ast11 = parent.Redirections[0] as FileRedirectionAst;
                        if (((ast11 != null) && (ast11.Extent.EndLineNumber == lastAst.Extent.StartLineNumber)) && (ast11.Extent.EndColumnNumber == lastAst.Extent.StartColumnNumber))
                        {
                            string str5 = CompletionCompleters.ConcatenateStringPathArguments(ast11.Location, tokenAtCursor.Text, completionContext);
                            if (str5 != null)
                            {
                                flag4 = true;
                                completionContext.WordToComplete = str5;
                                replacementIndex   = ast11.Location.Extent.StartScriptPosition.Offset;
                                replacementLength += ast11.Location.Extent.EndScriptPosition.Offset - replacementIndex;
                                completionContext.ReplacementIndex  = replacementIndex;
                                completionContext.ReplacementLength = replacementLength;
                            }
                        }
                    }
                }
                if (flag4)
                {
                    return(new List <CompletionResult>(CompletionCompleters.CompleteFilename(completionContext)));
                }
                string str6 = CompletionCompleters.ConcatenateStringPathArguments(lastAst as CommandElementAst, string.Empty, completionContext);
                if (str6 != null)
                {
                    completionContext.WordToComplete = str6;
                }
                source            = CompletionCompleters.CompleteCommandArgument(completionContext);
                replacementIndex  = completionContext.ReplacementIndex;
                replacementLength = completionContext.ReplacementLength;
            }
            return(source);
        }
예제 #17
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     return Ast.EmptyPSTypeNameArray;
 }
예제 #18
0
        /// <summary>
        /// Complete file name as command
        /// </summary>
        /// <param name="completionContext"></param>
        /// <returns></returns>
        private static List<CompletionResult> CompleteFileNameAsCommand(CompletionContext completionContext)
        {
            var addAmpersandIfNecessary = CompletionCompleters.IsAmpersandNeeded(completionContext, true);
            var result = new List<CompletionResult>();
            var clearLiteralPathsKey = false;

            if (completionContext.Options == null)
            {
                completionContext.Options = new Hashtable { { "LiteralPaths", true } };
            }
            else if (!completionContext.Options.ContainsKey("LiteralPaths"))
            {
                // Dont escape '[',']','`' when the file name is treated as command name
                completionContext.Options.Add("LiteralPaths", true);
                clearLiteralPathsKey = true;
            }

            try
            {
                var fileNameResult = CompletionCompleters.CompleteFilename(completionContext);
                foreach (var entry in fileNameResult)
                {
                    // Add '&' to file names that are quoted
                    var completionText = entry.CompletionText;
                    var len = completionText.Length;
                    if (addAmpersandIfNecessary && len > 2 && completionText[0].IsSingleQuote() && completionText[len - 1].IsSingleQuote())
                    {
                        completionText = "& " + completionText;
                        result.Add(new CompletionResult(completionText, entry.ListItemText, entry.ResultType, entry.ToolTip));
                    }
                    else
                    {
                        result.Add(entry);
                    }
                }
            }
            finally
            {
                if (clearLiteralPathsKey)
                    completionContext.Options.Remove("LiteralPaths");
            }

            return result;
        }
예제 #19
0
        private List<CompletionResult> GetResultForAttributeArgument(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength)
        {
            //Attribute member arguments
            Type attributeType = null;
            string argName = string.Empty;
            Ast argAst = completionContext.RelatedAsts.Find(ast => ast is NamedAttributeArgumentAst);
            NamedAttributeArgumentAst namedArgAst = argAst as NamedAttributeArgumentAst;
            if (argAst != null && namedArgAst != null)
            {
                attributeType = ((AttributeAst)namedArgAst.Parent).TypeName.GetReflectionAttributeType();
                argName = namedArgAst.ArgumentName;
                replacementIndex = namedArgAst.Extent.StartOffset;
                replacementLength = argName.Length;
            }
            else
            {
                Ast astAtt = completionContext.RelatedAsts.Find(ast => ast is AttributeAst);
                AttributeAst attAst = astAtt as AttributeAst;
                if (astAtt != null && attAst != null)
                {
                    attributeType = attAst.TypeName.GetReflectionAttributeType();
                }
            }

            if (attributeType != null)
            {
                PropertyInfo[] propertyInfos = attributeType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                List<CompletionResult> result = new List<CompletionResult>();
                foreach (PropertyInfo pro in propertyInfos)
                {
                    //Ignore TypeId (all attributes inherit it)
                    if (pro.Name != "TypeId" && (pro.Name.StartsWith(argName, StringComparison.OrdinalIgnoreCase)))
                    {
                        result.Add(new CompletionResult(pro.Name, pro.Name, CompletionResultType.Property,
                            pro.PropertyType.ToString() + " " + pro.Name));
                    }
                }
                return result;
            }
            return null;
        }
예제 #20
0
        private List<CompletionResult> GetResultForIdentifier(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength, bool isQuotedString)
        {
            var tokenAtCursor = completionContext.TokenAtCursor;
            var lastAst = completionContext.RelatedAsts.Last();

            List<CompletionResult> result = null;
            completionContext.WordToComplete = tokenAtCursor.Text;

            var strConst = lastAst as StringConstantExpressionAst;
            if (strConst != null)
            {
                if (strConst.Value.Equals("$", StringComparison.Ordinal))
                {
                    completionContext.WordToComplete = "";
                    return CompletionCompleters.CompleteVariable(completionContext);
                }
                else
                {
                    UsingStatementAst usingState = strConst.Parent as UsingStatementAst;
                    if (usingState != null)
                    {
                        completionContext.ReplacementIndex = strConst.Extent.StartOffset;
                        completionContext.ReplacementLength = strConst.Extent.EndOffset - replacementIndex;
                        completionContext.WordToComplete = strConst.Extent.Text;
                        switch (usingState.UsingStatementKind)
                        {
                            case UsingStatementKind.Assembly:
                                break;
                            case UsingStatementKind.Command:
                                break;
                            case UsingStatementKind.Module:
                                var moduleExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
                                {
                                    StringLiterals.PowerShellModuleFileExtension,
                                    StringLiterals.PowerShellDataFileExtension,
                                    StringLiterals.PowerShellNgenAssemblyExtension,
                                    StringLiterals.DependentWorkflowAssemblyExtension,
                                    StringLiterals.PowerShellCmdletizationFileExtension,
                                    StringLiterals.WorkflowFileExtension
                                };
                                result = CompletionCompleters.CompleteFilename(completionContext, false, moduleExtensions).ToList();
                                if (completionContext.WordToComplete.IndexOfAny(Utils.Separators.DirectoryOrDrive) != -1)
                                {
                                    // The partial input is a path, then we don't iterate modules under $ENV:PSModulePath
                                    return result;
                                }

                                var moduleResults = CompletionCompleters.CompleteModuleName(completionContext, false);
                                if (moduleResults != null && moduleResults.Count > 0)
                                    result.AddRange(moduleResults);
                                return result;
                            case UsingStatementKind.Namespace:
                                result = CompletionCompleters.CompleteNamespace(completionContext);
                                return result;
                            case UsingStatementKind.Type:
                                break;
                            default:
                                throw new ArgumentOutOfRangeException("UsingStatementKind");
                        }
                    }
                }
            }
            result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
            if (result != null) return result;

            if ((tokenAtCursor.TokenFlags & TokenFlags.CommandName) != 0)
            {
                // Handle completion for a path with variable, such as: $PSHOME\ty<tab>
                if (completionContext.RelatedAsts.Count > 0 && completionContext.RelatedAsts[0] is ScriptBlockAst)
                {
                    Ast cursorAst = null;
                    var cursorPosition = (InternalScriptPosition)_cursorPosition;
                    int offsetBeforeCmdName = cursorPosition.Offset - tokenAtCursor.Text.Length;
                    if (offsetBeforeCmdName >= 0)
                    {
                        var cursorBeforeCmdName = cursorPosition.CloneWithNewOffset(offsetBeforeCmdName);
                        var scriptBlockAst = (ScriptBlockAst)completionContext.RelatedAsts[0];
                        cursorAst = GetLastAstAtCursor(scriptBlockAst, cursorBeforeCmdName);
                    }

                    if (cursorAst != null &&
                        cursorAst.Extent.EndLineNumber == tokenAtCursor.Extent.StartLineNumber &&
                        cursorAst.Extent.EndColumnNumber == tokenAtCursor.Extent.StartColumnNumber)
                    {
                        if (tokenAtCursor.Text.IndexOfAny(Utils.Separators.Directory) == 0)
                        {
                            string wordToComplete =
                                CompletionCompleters.ConcatenateStringPathArguments(cursorAst as CommandElementAst, tokenAtCursor.Text, completionContext);
                            if (wordToComplete != null)
                            {
                                completionContext.WordToComplete = wordToComplete;
                                result = new List<CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
                                if (result.Count > 0)
                                {
                                    replacementIndex = cursorAst.Extent.StartScriptPosition.Offset;
                                    replacementLength += cursorAst.Extent.Text.Length;
                                }
                                return result;
                            }
                            else
                            {
                                var variableAst = cursorAst as VariableExpressionAst;
                                string fullPath = variableAst != null
                                    ? CompletionCompleters.CombineVariableWithPartialPath(
                                        variableAst: variableAst,
                                        extraText: tokenAtCursor.Text,
                                        executionContext: completionContext.ExecutionContext)
                                    : null;

                                if (fullPath == null) { return result; }

                                // Continue trying the filename/commandname completion for scenarios like this: $aa\d<tab>
                                completionContext.WordToComplete = fullPath;
                                replacementIndex = cursorAst.Extent.StartScriptPosition.Offset;
                                replacementLength += cursorAst.Extent.Text.Length;

                                completionContext.ReplacementIndex = replacementIndex;
                                completionContext.ReplacementLength = replacementLength;
                            }
                        }
                        // Continue trying the filename/commandname completion for scenarios like this: $aa[get-<tab>
                        else if (!(cursorAst is ErrorExpressionAst && cursorAst.Parent is IndexExpressionAst))
                        {
                            return result;
                        }
                    }
                }

                // When it's the content of a quoted string, we only handle variable/member completion
                if (isQuotedString) { return result; }

                // Handle the StringExpandableToken;
                var strToken = tokenAtCursor as StringExpandableToken;
                if (strToken != null && strToken.NestedTokens != null && strConst != null)
                {
                    try
                    {
                        string expandedString = null;
                        var expandableStringAst = new ExpandableStringExpressionAst(strConst.Extent, strConst.Value, StringConstantType.BareWord);
                        if (CompletionCompleters.IsPathSafelyExpandable(expandableStringAst: expandableStringAst,
                                                                        extraText: String.Empty,
                                                                        executionContext: completionContext.ExecutionContext,
                                                                        expandedString: out expandedString))
                        {
                            completionContext.WordToComplete = expandedString;
                        }
                        else
                        {
                            return result;
                        }
                    }
                    catch (Exception e)
                    {
                        CommandProcessorBase.CheckForSevereException(e);
                        return result;
                    }
                }

                //
                // Handle completion of DSC resources within Configuration
                //
                DynamicKeywordStatementAst keywordAst;
                ConfigurationDefinitionAst configureAst = GetAncestorConfigurationAstAndKeywordAst(completionContext.CursorPosition, lastAst, out keywordAst);
                bool matched = false;
                List<CompletionResult> keywordResult = null;
                if (configureAst != null)
                {
                    // Current token is within ConfigurationDefinitionAst or DynamicKeywordStatementAst
                    keywordResult = GetResultForIdentifierInConfiguration(completionContext, configureAst, keywordAst, out matched);
                }

                // Handle the file completion before command name completion
                result = CompleteFileNameAsCommand(completionContext);
                // Handle the command name completion
                var commandNameResult = CompletionCompleters.CompleteCommand(completionContext);

                if (commandNameResult != null && commandNameResult.Count > 0)
                {
                    result.AddRange(commandNameResult);
                }

                if (matched && keywordResult != null)
                {
                    result.InsertRange(0, keywordResult);
                }
                else if (!matched && keywordResult != null && commandNameResult.Count == 0)
                {
                    result.AddRange(keywordResult);
                }
                return result;
            }

            if (tokenAtCursor.Text.Length == 1 && tokenAtCursor.Text[0].IsDash() && (lastAst.Parent is CommandAst || lastAst.Parent is DynamicKeywordStatementAst))
            {
                // When it's the content of a quoted string, we only handle variable/member completion
                if (isQuotedString) { return result; }
                return CompletionCompleters.CompleteCommandParameter(completionContext);
            }

            TokenKind memberOperator = TokenKind.Unknown;
            bool isMemberCompletion = (lastAst.Parent is MemberExpressionAst);
            bool isStatic = isMemberCompletion ? ((MemberExpressionAst)lastAst.Parent).Static : false;
            bool isWildcard = false;

            if (!isMemberCompletion)
            {
                // Still might be member completion, something like: echo $member.
                // We need to know if the previous element before the token is adjacent because
                // we don't have a MemberExpressionAst, we might have 2 command arguments.

                if (tokenAtCursor.Text.Equals(TokenKind.Dot.Text(), StringComparison.Ordinal))
                {
                    memberOperator = TokenKind.Dot;
                    isMemberCompletion = true;
                }
                else if (tokenAtCursor.Text.Equals(TokenKind.ColonColon.Text(), StringComparison.Ordinal))
                {
                    memberOperator = TokenKind.ColonColon;
                    isMemberCompletion = true;
                }
                else if (tokenAtCursor.Kind.Equals(TokenKind.Multiply) && lastAst is BinaryExpressionAst)
                {
                    // Handle member completion with wildcard(wildcard is at the end): $a.p*
                    var binaryExpressionAst = (BinaryExpressionAst)lastAst;
                    var memberExpressionAst = binaryExpressionAst.Left as MemberExpressionAst;
                    var errorPosition = binaryExpressionAst.ErrorPosition;

                    if (memberExpressionAst != null && binaryExpressionAst.Operator == TokenKind.Multiply &&
                        errorPosition.StartOffset == memberExpressionAst.Member.Extent.EndOffset)
                    {
                        isStatic = memberExpressionAst.Static;
                        memberOperator = isStatic ? TokenKind.ColonColon : TokenKind.Dot;
                        isMemberCompletion = true;
                        isWildcard = true;

                        // Member completion will add back the '*', so pretend it wasn't there, at least from the "related asts" point of view,
                        // but add the member expression that we are really completing.
                        completionContext.RelatedAsts.Remove(binaryExpressionAst);
                        completionContext.RelatedAsts.Add(memberExpressionAst);

                        var memberAst = memberExpressionAst.Member as StringConstantExpressionAst;
                        if (memberAst != null)
                        {
                            replacementIndex = memberAst.Extent.StartScriptPosition.Offset;
                            replacementLength += memberAst.Extent.Text.Length;
                        }
                    }
                }
            }

            if (isMemberCompletion)
            {
                result = CompletionCompleters.CompleteMember(completionContext, @static: (isStatic || memberOperator == TokenKind.ColonColon));

                // If the last token was just a '.', we tried to complete members.  That may
                // have failed because it wasn't really an attempt to complete a member, in
                // which case we should try to complete as an argument.
                if (result.Any())
                {
                    if (!isWildcard && memberOperator != TokenKind.Unknown)
                    {
                        replacementIndex += tokenAtCursor.Text.Length;
                        replacementLength = 0;
                    }
                    return result;
                }
            }

            if (lastAst.Parent is HashtableAst)
            {
                result = CompletionCompleters.CompleteHashtableKey(completionContext, (HashtableAst)lastAst.Parent);
                if (result != null && result.Any())
                {
                    return result;
                }
            }

            // When it's the content of a quoted string, we only handle variable/member completion
            if (isQuotedString) { return result; }

            bool needFileCompletion = false;
            if (lastAst.Parent is FileRedirectionAst || CompleteAgainstSwitchFile(lastAst, completionContext.TokenBeforeCursor))
            {
                string wordToComplete =
                    CompletionCompleters.ConcatenateStringPathArguments(lastAst as CommandElementAst, String.Empty, completionContext);
                if (wordToComplete != null)
                {
                    needFileCompletion = true;
                    completionContext.WordToComplete = wordToComplete;
                }
            }
            else if (tokenAtCursor.Text.IndexOfAny(Utils.Separators.Directory) == 0)
            {
                var command = lastAst.Parent as CommandBaseAst;
                if (command != null && command.Redirections.Any())
                {
                    var fileRedirection = command.Redirections[0] as FileRedirectionAst;
                    if (fileRedirection != null &&
                        fileRedirection.Extent.EndLineNumber == lastAst.Extent.StartLineNumber &&
                        fileRedirection.Extent.EndColumnNumber == lastAst.Extent.StartColumnNumber)
                    {
                        string wordToComplete =
                            CompletionCompleters.ConcatenateStringPathArguments(fileRedirection.Location, tokenAtCursor.Text, completionContext);

                        if (wordToComplete != null)
                        {
                            needFileCompletion = true;
                            completionContext.WordToComplete = wordToComplete;
                            replacementIndex = fileRedirection.Location.Extent.StartScriptPosition.Offset;
                            replacementLength += fileRedirection.Location.Extent.EndScriptPosition.Offset - replacementIndex;

                            completionContext.ReplacementIndex = replacementIndex;
                            completionContext.ReplacementLength = replacementLength;
                        }
                    }
                }
            }

            if (needFileCompletion)
            {
                return new List<CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
            }
            else
            {
                string wordToComplete =
                    CompletionCompleters.ConcatenateStringPathArguments(lastAst as CommandElementAst, String.Empty, completionContext);
                if (wordToComplete != null)
                {
                    completionContext.WordToComplete = wordToComplete;
                }
            }

            result = CompletionCompleters.CompleteCommandArgument(completionContext);
            replacementIndex = completionContext.ReplacementIndex;
            replacementLength = completionContext.ReplacementLength;
            return result;
        }
예제 #21
0
        /// <summary>
        /// Generate auto complete results for identifier within configuration.
        /// Results are generated based on DynamicKeywords matches given identifier.
        /// For example, following "Fi" matches "File", and "Us" matches "User"
        /// 
        ///     Configuration
        ///     {
        ///         Fi^
        ///         Node("TargetMachine")
        ///         {
        ///             Us^
        ///         }
        ///     }
        /// 
        /// </summary>
        /// <param name="completionContext"></param>
        /// <param name="configureAst"></param>
        /// <param name="keywordAst"></param>
        /// <param name="matched"></param>
        /// <returns></returns>
        private List<CompletionResult> GetResultForIdentifierInConfiguration(
            CompletionContext completionContext,
            ConfigurationDefinitionAst configureAst,
            DynamicKeywordStatementAst keywordAst,
            out bool matched)
        {
            List<CompletionResult> results = null;
            matched = false;

#if CORECLR // Microsoft.PowerShell.DesiredStateConfiguration is not in CORE CLR
            results = new List<CompletionResult>();
#else
            IEnumerable<DynamicKeyword> keywords = configureAst.DefinedKeywords.Where(
                k => // Node is special case, legal in both Resource and Meta configuration
                    String.Compare(k.Keyword, @"Node", StringComparison.OrdinalIgnoreCase) == 0 ||
                    (
                        // Check compatibility between Resource and Configuration Type
                        k.IsCompatibleWithConfigurationType(configureAst.ConfigurationType) &&
                        !DynamicKeyword.IsHiddenKeyword(k.Keyword) &&
                        !k.IsReservedKeyword
                    )
            );

            if (keywordAst != null && completionContext.CursorPosition.Offset < keywordAst.Extent.EndOffset)
                keywords = keywordAst.Keyword.GetAllowedKeywords(keywords);

            if (keywords != null && keywords.Any())
            {
                string commandName = (completionContext.WordToComplete ?? String.Empty) + "*";
                var wildcardPattern = WildcardPattern.Get(commandName, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant);

                // Filter by name
                var matchedResults = keywords.Where(k => wildcardPattern.IsMatch(k.Keyword));
                if (matchedResults == null || !matchedResults.Any())
                {
                    // Fallback to all legal keywords in the configuration statement
                    matchedResults = keywords;
                }
                else
                {
                    matched = true;
                }

                foreach (var keyword in matchedResults)
                {
                    string usageString = Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache.GetDSCResourceUsageString(keyword);
                    if (results == null)
                    {
                        results = new List<CompletionResult>();
                    }
                    results.Add(new CompletionResult(
                        keyword.Keyword,
                        keyword.Keyword,
                        CompletionResultType.DynamicKeyword,
                        usageString));
                }
            }
#endif

            return results;
        }
예제 #22
0
파일: CommandAst.cs 프로젝트: nickchal/pash
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     PseudoBindingInfo iteratorVariable0 = new PseudoParameterBinder().DoPseudoParameterBinding(this, null, null, false);
     if (iteratorVariable0.CommandInfo != null)
     {
         AstParameterArgumentPair iteratorVariable1;
         string key = "Path";
         if (!iteratorVariable0.BoundArguments.TryGetValue(key, out iteratorVariable1))
         {
             key = "LiteralPath";
             iteratorVariable0.BoundArguments.TryGetValue(key, out iteratorVariable1);
         }
         CommandInfo commandInfo = iteratorVariable0.CommandInfo;
         AstPair iteratorVariable4 = iteratorVariable1 as AstPair;
         if ((iteratorVariable4 != null) && (iteratorVariable4.Argument is StringConstantExpressionAst))
         {
             string str = ((StringConstantExpressionAst) iteratorVariable4.Argument).Value;
             try
             {
                 commandInfo = commandInfo.CreateGetCommandCopy(new string[] { "-" + key, str });
             }
             catch (InvalidOperationException)
             {
             }
         }
         CmdletInfo iteratorVariable5 = commandInfo as CmdletInfo;
         if (iteratorVariable5 != null)
         {
             if (iteratorVariable5.ImplementingType.FullName.Equals("Microsoft.PowerShell.Commands.NewObjectCommand", StringComparison.Ordinal))
             {
                 AstParameterArgumentPair iteratorVariable6;
                 if (iteratorVariable0.BoundArguments.TryGetValue("TypeName", out iteratorVariable6))
                 {
                     AstPair iteratorVariable7 = iteratorVariable6 as AstPair;
                     if ((iteratorVariable7 != null) && (iteratorVariable7.Argument is StringConstantExpressionAst))
                     {
                         yield return new PSTypeName(((StringConstantExpressionAst) iteratorVariable7.Argument).Value);
                     }
                 }
                 goto Label_0579;
             }
             if (iteratorVariable5.ImplementingType.Equals(typeof(WhereObjectCommand)) || iteratorVariable5.ImplementingType.FullName.Equals("Microsoft.PowerShell.Commands.SortObjectCommand", StringComparison.Ordinal))
             {
                 PipelineAst parent = this.Parent as PipelineAst;
                 if (parent != null)
                 {
                     int iteratorVariable9 = 0;
                     while (iteratorVariable9 < parent.PipelineElements.Count)
                     {
                         if (parent.PipelineElements[iteratorVariable9] == this)
                         {
                             break;
                         }
                         iteratorVariable9++;
                     }
                     if (iteratorVariable9 > 0)
                     {
                         foreach (PSTypeName iteratorVariable10 in parent.PipelineElements[iteratorVariable9 - 1].GetInferredType(context))
                         {
                             yield return iteratorVariable10;
                         }
                     }
                 }
                 goto Label_0579;
             }
             if (iteratorVariable5.ImplementingType.Equals(typeof(ForEachObjectCommand)))
             {
                 AstParameterArgumentPair iteratorVariable11;
                 if (iteratorVariable0.BoundArguments.TryGetValue("Begin", out iteratorVariable11))
                 {
                     foreach (PSTypeName iteratorVariable12 in this.GetInferredTypeFromScriptBlockParameter(iteratorVariable11, context))
                     {
                         yield return iteratorVariable12;
                     }
                 }
                 if (iteratorVariable0.BoundArguments.TryGetValue("Process", out iteratorVariable11))
                 {
                     foreach (PSTypeName iteratorVariable13 in this.GetInferredTypeFromScriptBlockParameter(iteratorVariable11, context))
                     {
                         yield return iteratorVariable13;
                     }
                 }
                 if (iteratorVariable0.BoundArguments.TryGetValue("End", out iteratorVariable11))
                 {
                     foreach (PSTypeName iteratorVariable14 in this.GetInferredTypeFromScriptBlockParameter(iteratorVariable11, context))
                     {
                         yield return iteratorVariable14;
                     }
                 }
             }
         }
         foreach (PSTypeName iteratorVariable15 in commandInfo.OutputType)
         {
             yield return iteratorVariable15;
         }
     }
 Label_0579:
     yield break;
 }
예제 #23
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     return this.Statements.SelectMany(ast => ast.GetInferredType(context));
 }
예제 #24
0
 private List<CompletionResult> GetResultForIdentifier(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength, bool isQuotedString)
 {
     Token tokenAtCursor = completionContext.TokenAtCursor;
     Ast lastAst = completionContext.RelatedAsts.Last<Ast>();
     List<CompletionResult> source = null;
     completionContext.WordToComplete = tokenAtCursor.Text;
     StringConstantExpressionAst ast2 = lastAst as StringConstantExpressionAst;
     if ((ast2 != null) && ast2.Value.Equals("$", StringComparison.Ordinal))
     {
         completionContext.WordToComplete = "";
         return CompletionCompleters.CompleteVariable(completionContext);
     }
     if ((tokenAtCursor.TokenFlags & TokenFlags.CommandName) != TokenFlags.None)
     {
         if ((completionContext.RelatedAsts.Count > 0) && (completionContext.RelatedAsts[0] is ScriptBlockAst))
         {
             Ast lastAstAtCursor = null;
             InternalScriptPosition position = (InternalScriptPosition) this._cursorPosition;
             int offset = position.Offset - tokenAtCursor.Text.Length;
             if (offset >= 0)
             {
                 InternalScriptPosition cursorPosition = position.CloneWithNewOffset(offset);
                 ScriptBlockAst scriptBlockAst = (ScriptBlockAst) completionContext.RelatedAsts[0];
                 lastAstAtCursor = GetLastAstAtCursor(scriptBlockAst, cursorPosition);
             }
             if (((lastAstAtCursor != null) && (lastAstAtCursor.Extent.EndLineNumber == tokenAtCursor.Extent.StartLineNumber)) && (lastAstAtCursor.Extent.EndColumnNumber == tokenAtCursor.Extent.StartColumnNumber))
             {
                 if (tokenAtCursor.Text.IndexOfAny(new char[] { '\\', '/' }) == 0)
                 {
                     string str = CompletionCompleters.ConcatenateStringPathArguments(lastAstAtCursor as CommandElementAst, tokenAtCursor.Text, completionContext);
                     if (str != null)
                     {
                         completionContext.WordToComplete = str;
                         source = new List<CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
                         if (source.Count > 0)
                         {
                             replacementIndex = lastAstAtCursor.Extent.StartScriptPosition.Offset;
                             replacementLength += lastAstAtCursor.Extent.Text.Length;
                         }
                         return source;
                     }
                     VariableExpressionAst variableAst = lastAstAtCursor as VariableExpressionAst;
                     string str2 = (variableAst != null) ? CompletionCompleters.CombineVariableWithPartialPath(variableAst, tokenAtCursor.Text, completionContext.ExecutionContext) : null;
                     if (str2 == null)
                     {
                         return source;
                     }
                     completionContext.WordToComplete = str2;
                     replacementIndex = lastAstAtCursor.Extent.StartScriptPosition.Offset;
                     replacementLength += lastAstAtCursor.Extent.Text.Length;
                     completionContext.ReplacementIndex = replacementIndex;
                     completionContext.ReplacementLength = replacementLength;
                 }
                 else if (!(lastAstAtCursor is ErrorExpressionAst) || !(lastAstAtCursor.Parent is IndexExpressionAst))
                 {
                     return source;
                 }
             }
         }
         if (!isQuotedString)
         {
             StringExpandableToken token2 = tokenAtCursor as StringExpandableToken;
             if (((token2 != null) && (token2.NestedTokens != null)) && (ast2 != null))
             {
                 try
                 {
                     string expandedString = null;
                     ExpandableStringExpressionAst expandableStringAst = new ExpandableStringExpressionAst(ast2.Extent, ast2.Value, StringConstantType.BareWord);
                     if (CompletionCompleters.IsPathSafelyExpandable(expandableStringAst, string.Empty, completionContext.ExecutionContext, out expandedString))
                     {
                         completionContext.WordToComplete = expandedString;
                     }
                     else
                     {
                         return source;
                     }
                 }
                 catch (Exception exception)
                 {
                     CommandProcessorBase.CheckForSevereException(exception);
                     return source;
                 }
             }
             source = CompleteFileNameAsCommand(completionContext);
             List<CompletionResult> collection = CompletionCompleters.CompleteCommand(completionContext);
             if ((collection != null) && (collection.Count > 0))
             {
                 source.AddRange(collection);
             }
         }
         return source;
     }
     if (((tokenAtCursor.Text.Length == 1) && tokenAtCursor.Text[0].IsDash()) && (lastAst.Parent is CommandAst))
     {
         if (isQuotedString)
         {
             return source;
         }
         return CompletionCompleters.CompleteCommandParameter(completionContext);
     }
     TokenKind unknown = TokenKind.Unknown;
     bool flag = lastAst.Parent is MemberExpressionAst;
     bool @static = flag ? ((MemberExpressionAst) lastAst.Parent).Static : false;
     bool flag3 = false;
     if (!flag)
     {
         if (tokenAtCursor.Text.Equals(TokenKind.Dot.Text(), StringComparison.Ordinal))
         {
             unknown = TokenKind.Dot;
             flag = true;
         }
         else if (tokenAtCursor.Text.Equals(TokenKind.ColonColon.Text(), StringComparison.Ordinal))
         {
             unknown = TokenKind.ColonColon;
             flag = true;
         }
         else if (tokenAtCursor.Kind.Equals(TokenKind.Multiply) && (lastAst is BinaryExpressionAst))
         {
             BinaryExpressionAst item = (BinaryExpressionAst) lastAst;
             MemberExpressionAst left = item.Left as MemberExpressionAst;
             IScriptExtent errorPosition = item.ErrorPosition;
             if (((left != null) && (item.Operator == TokenKind.Multiply)) && (errorPosition.StartOffset == left.Member.Extent.EndOffset))
             {
                 @static = left.Static;
                 unknown = @static ? TokenKind.ColonColon : TokenKind.Dot;
                 flag = true;
                 flag3 = true;
                 completionContext.RelatedAsts.Remove(item);
                 completionContext.RelatedAsts.Add(left);
                 StringConstantExpressionAst member = left.Member as StringConstantExpressionAst;
                 if (member != null)
                 {
                     replacementIndex = member.Extent.StartScriptPosition.Offset;
                     replacementLength += member.Extent.Text.Length;
                 }
             }
         }
     }
     if (flag)
     {
         source = CompletionCompleters.CompleteMember(completionContext, @static || (unknown == TokenKind.ColonColon));
         if (source.Any<CompletionResult>())
         {
             if (!flag3 && (unknown != TokenKind.Unknown))
             {
                 replacementIndex += tokenAtCursor.Text.Length;
                 replacementLength = 0;
             }
             return source;
         }
     }
     if (lastAst.Parent is HashtableAst)
     {
         source = CompletionCompleters.CompleteHashtableKey(completionContext, (HashtableAst) lastAst.Parent);
         if ((source != null) && source.Any<CompletionResult>())
         {
             return source;
         }
     }
     if (!isQuotedString)
     {
         bool flag4 = false;
         if ((lastAst.Parent is FileRedirectionAst) || CompleteAgainstSwitchFile(lastAst, completionContext.TokenBeforeCursor))
         {
             string str4 = CompletionCompleters.ConcatenateStringPathArguments(lastAst as CommandElementAst, string.Empty, completionContext);
             if (str4 != null)
             {
                 flag4 = true;
                 completionContext.WordToComplete = str4;
             }
         }
         else if (tokenAtCursor.Text.IndexOfAny(new char[] { '\\', '/' }) == 0)
         {
             CommandBaseAst parent = lastAst.Parent as CommandBaseAst;
             if ((parent != null) && parent.Redirections.Any<RedirectionAst>())
             {
                 FileRedirectionAst ast11 = parent.Redirections[0] as FileRedirectionAst;
                 if (((ast11 != null) && (ast11.Extent.EndLineNumber == lastAst.Extent.StartLineNumber)) && (ast11.Extent.EndColumnNumber == lastAst.Extent.StartColumnNumber))
                 {
                     string str5 = CompletionCompleters.ConcatenateStringPathArguments(ast11.Location, tokenAtCursor.Text, completionContext);
                     if (str5 != null)
                     {
                         flag4 = true;
                         completionContext.WordToComplete = str5;
                         replacementIndex = ast11.Location.Extent.StartScriptPosition.Offset;
                         replacementLength += ast11.Location.Extent.EndScriptPosition.Offset - replacementIndex;
                         completionContext.ReplacementIndex = replacementIndex;
                         completionContext.ReplacementLength = replacementLength;
                     }
                 }
             }
         }
         if (flag4)
         {
             return new List<CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
         }
         string str6 = CompletionCompleters.ConcatenateStringPathArguments(lastAst as CommandElementAst, string.Empty, completionContext);
         if (str6 != null)
         {
             completionContext.WordToComplete = str6;
         }
         source = CompletionCompleters.CompleteCommandArgument(completionContext);
         replacementIndex = completionContext.ReplacementIndex;
         replacementLength = completionContext.ReplacementLength;
     }
     return source;
 }
예제 #25
0
 private static List<CompletionResult> CompleteFileNameAsCommand(CompletionContext completionContext)
 {
     bool flag = CompletionCompleters.IsAmpersandNeeded(completionContext, true);
     List<CompletionResult> list = new List<CompletionResult>();
     bool flag2 = false;
     if (completionContext.Options == null)
     {
         Hashtable hashtable = new Hashtable();
         hashtable.Add("LiteralPaths", true);
         completionContext.Options = hashtable;
     }
     else if (!completionContext.Options.ContainsKey("LiteralPaths"))
     {
         completionContext.Options.Add("LiteralPaths", true);
         flag2 = true;
     }
     try
     {
         foreach (CompletionResult result in CompletionCompleters.CompleteFilename(completionContext))
         {
             string completionText = result.CompletionText;
             int length = completionText.Length;
             if ((flag && (length > 2)) && (completionText[0].IsSingleQuote() && completionText[length - 1].IsSingleQuote()))
             {
                 completionText = "& " + completionText;
                 list.Add(new CompletionResult(completionText, result.ListItemText, result.ResultType, result.ToolTip));
             }
             else
             {
                 list.Add(result);
             }
         }
     }
     finally
     {
         if (flag2)
         {
             completionContext.Options.Remove("LiteralPaths");
         }
     }
     return list;
 }
예제 #26
0
        private List <CompletionResult> GetResultForString(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength, bool isQuotedString)
        {
            if (isQuotedString)
            {
                return(null);
            }
            Token tokenAtCursor = completionContext.TokenAtCursor;
            Ast   ast           = completionContext.RelatedAsts.Last <Ast>();
            List <CompletionResult>       list = null;
            ExpandableStringExpressionAst ast2 = ast as ExpandableStringExpressionAst;
            StringConstantExpressionAst   ast3 = ast as StringConstantExpressionAst;

            if ((ast3 != null) || (ast2 != null))
            {
                string             input = (ast3 != null) ? ast3.Value : ast2.Value;
                StringConstantType type  = (ast3 != null) ? ast3.StringConstantType : ast2.StringConstantType;
                string             str2  = null;
                if (type == StringConstantType.DoubleQuoted)
                {
                    Match match = Regex.Match(input, @"(\$[\w\d]+\.[\w\d\*]*)$");
                    if (match.Success)
                    {
                        str2 = match.Groups[1].Value;
                    }
                    else if ((match = Regex.Match(input, @"(\[[\w\d\.]+\]::[\w\d\*]*)$")).Success)
                    {
                        str2 = match.Groups[1].Value;
                    }
                }
                if (str2 != null)
                {
                    int num3;
                    int num4;
                    int offset = tokenAtCursor.Extent.StartScriptPosition.Offset;
                    int length = (this._cursorPosition.Offset - offset) - 1;
                    if (length >= input.Length)
                    {
                        length = input.Length;
                    }
                    CompletionAnalysis analysis = new CompletionAnalysis(this._ast, this._tokens, this._cursorPosition, this._options);
                    CompletionContext  context  = analysis.CreateCompletionContext(completionContext.ExecutionContext);
                    context.Helper = completionContext.Helper;
                    List <CompletionResult> list2 = analysis.GetResultHelper(context, out num3, out num4, true);
                    if ((list2 != null) && (list2.Count > 0))
                    {
                        list              = new List <CompletionResult>();
                        replacementIndex  = (offset + 1) + (length - str2.Length);
                        replacementLength = str2.Length;
                        string str3 = str2.Substring(0, num3);
                        foreach (CompletionResult result in list2)
                        {
                            string completionText = str3 + result.CompletionText;
                            if (result.ResultType.Equals(CompletionResultType.Property))
                            {
                                completionText = TokenKind.DollarParen.Text() + completionText + TokenKind.RParen.Text();
                            }
                            else if (result.ResultType.Equals(CompletionResultType.Method))
                            {
                                completionText = TokenKind.DollarParen.Text() + completionText;
                            }
                            completionText = completionText + "\"";
                            list.Add(new CompletionResult(completionText, result.ListItemText, result.ResultType, result.ToolTip));
                        }
                    }
                    return(list);
                }
                CommandElementAst stringAst = ast as CommandElementAst;
                string            str5      = CompletionCompleters.ConcatenateStringPathArguments(stringAst, string.Empty, completionContext);
                if (str5 == null)
                {
                    return(list);
                }
                completionContext.WordToComplete = str5;
                if ((ast.Parent is CommandAst) || (ast.Parent is CommandParameterAst))
                {
                    list              = CompletionCompleters.CompleteCommandArgument(completionContext);
                    replacementIndex  = completionContext.ReplacementIndex;
                    replacementLength = completionContext.ReplacementLength;
                    return(list);
                }
                list = new List <CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
                if (str5.IndexOf('-') != -1)
                {
                    List <CompletionResult> collection = CompletionCompleters.CompleteCommand(completionContext);
                    if ((collection != null) && (collection.Count > 0))
                    {
                        list.AddRange(collection);
                    }
                }
            }
            return(list);
        }
예제 #27
0
        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;
        }
예제 #28
0
        internal List<CompletionResult> GetResultHelper(CompletionContext completionContext, out int replacementIndex, out int replacementLength, bool isQuotedString)
        {
            replacementIndex = -1;
            replacementLength = -1;

            var tokenAtCursor = completionContext.TokenAtCursor;
            var lastAst = completionContext.RelatedAsts.Last();
            List<CompletionResult> result = null;
            if (tokenAtCursor != null)
            {
                replacementIndex = tokenAtCursor.Extent.StartScriptPosition.Offset;
                replacementLength = tokenAtCursor.Extent.EndScriptPosition.Offset - replacementIndex;

                completionContext.ReplacementIndex = replacementIndex;
                completionContext.ReplacementLength = replacementLength;

                switch (tokenAtCursor.Kind)
                {
                    case TokenKind.Variable:
                    case TokenKind.SplattedVariable:
                        completionContext.WordToComplete = ((VariableToken)tokenAtCursor).VariablePath.UserPath;
                        result = CompletionCompleters.CompleteVariable(completionContext);
                        break;

                    case TokenKind.Multiply:
                    case TokenKind.Generic:
                    case TokenKind.Identifier:
                        result = GetResultForIdentifier(completionContext, ref replacementIndex, ref replacementLength, isQuotedString);
                        break;

                    case TokenKind.Parameter:
                        // When it's the content of a quoted string, we only handle variable/member completion
                        if (isQuotedString)
                            break;

                        completionContext.WordToComplete = tokenAtCursor.Text;
                        var cmdAst = lastAst.Parent as CommandAst;
                        if (lastAst is StringConstantExpressionAst && cmdAst != null && cmdAst.CommandElements.Count == 1)
                        {
                            result = CompleteFileNameAsCommand(completionContext);
                            break;
                        }

                        TokenKind statementKind;
                        if (CompleteAgainstStatementFlags(null, lastAst, null, out statementKind))
                        {
                            result = CompletionCompleters.CompleteStatementFlags(statementKind, completionContext.WordToComplete);
                            break;
                        }

                        if (CompleteOperator(tokenAtCursor, lastAst))
                        {
                            result = CompletionCompleters.CompleteOperator(completionContext.WordToComplete);
                            break;
                        }

                        // Handle scenarios like this: dir -path:<tab>
                        if (completionContext.WordToComplete.EndsWith(":", StringComparison.Ordinal))
                        {
                            replacementIndex = tokenAtCursor.Extent.EndScriptPosition.Offset;
                            replacementLength = 0;

                            completionContext.WordToComplete = string.Empty;
                            result = CompletionCompleters.CompleteCommandArgument(completionContext);
                        }
                        else
                        {
                            result = CompletionCompleters.CompleteCommandParameter(completionContext);
                        }
                        break;

                    case TokenKind.Dot:
                    case TokenKind.ColonColon:
                        replacementIndex += tokenAtCursor.Text.Length;
                        replacementLength = 0;
                        result = CompletionCompleters.CompleteMember(completionContext, @static: tokenAtCursor.Kind == TokenKind.ColonColon);
                        break;

                    case TokenKind.Comment:
                        // When it's the content of a quoted string, we only handle variable/member completion
                        if (isQuotedString)
                            break;

                        completionContext.WordToComplete = tokenAtCursor.Text;
                        result = CompletionCompleters.CompleteComment(completionContext);
                        break;

                    case TokenKind.StringExpandable:
                    case TokenKind.StringLiteral:
                        result = GetResultForString(completionContext, ref replacementIndex, ref replacementLength, isQuotedString);
                        break;

                    case TokenKind.RBracket:
                        if (lastAst is TypeExpressionAst)
                        {
                            var targetExpr = (TypeExpressionAst)lastAst;
                            var memberResult = new List<CompletionResult>();

                            CompletionCompleters.CompleteMemberHelper(
                                true,
                                "*",
                                targetExpr,
                                completionContext, memberResult);

                            if (memberResult.Count > 0)
                            {
                                replacementIndex++;
                                replacementLength = 0;
                                result = (from entry in memberResult
                                          let completionText = TokenKind.ColonColon.Text() + entry.CompletionText
                                          select new CompletionResult(completionText, entry.ListItemText, entry.ResultType, entry.ToolTip)).ToList();
                            }
                        }
                        break;

                    case TokenKind.Comma:
                        // Hanlde array elements such as dir .\cd,<tab> || dir -Path: .\cd,<tab>
                        if (lastAst is ErrorExpressionAst &&
                            (lastAst.Parent is CommandAst || lastAst.Parent is CommandParameterAst))
                        {
                            replacementIndex += replacementLength;
                            replacementLength = 0;

                            result = CompletionCompleters.CompleteCommandArgument(completionContext);
                        }
                        else
                        {
                            //
                            // Handle auto completion for enum/dependson property of DSC resource,
                            // cursor is right after ','
                            //
                            // Configuration config
                            // {
                            //     User test
                            //     {
                            //         DependsOn=@('[user]x',|)
                            //
                            bool unused;
                            result = GetResultForEnumPropertyValueOfDSCResource(completionContext, string.Empty, ref replacementIndex, ref replacementLength, out unused);
                        }
                        break;

                    case TokenKind.Number:
                        // Handle scenarios such as Get-Process -Id 5<tab> || Get-Process -Id 5210, 3<tab> || Get-Process -Id: 5210, 3<tab>
                        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;
                            result = CompletionCompleters.CompleteCommandArgument(completionContext);

                            replacementIndex = completionContext.ReplacementIndex;
                            replacementLength = completionContext.ReplacementLength;
                        }
                        break;

                    case TokenKind.Redirection:
                        // Handle file name completion after the redirection operator: gps ><tab> || gps >><tab> || dir con 2><tab> || dir con 2>><tab>
                        if (lastAst is ErrorExpressionAst && lastAst.Parent is FileRedirectionAst)
                        {
                            completionContext.WordToComplete = string.Empty;
                            completionContext.ReplacementIndex = (replacementIndex += tokenAtCursor.Text.Length);
                            completionContext.ReplacementLength = replacementLength = 0;
                            result = new List<CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
                        }
                        break;

                    case TokenKind.Minus:
                        // Handle operator completion: 55 -<tab> || "string" -<tab> || (Get-Something) -<tab>
                        if (CompleteOperator(tokenAtCursor, lastAst))
                        {
                            result = CompletionCompleters.CompleteOperator("");
                            break;
                        }

                        // Handle the flag completion for statements, such as the switch statement
                        if (CompleteAgainstStatementFlags(completionContext.RelatedAsts[0], null, tokenAtCursor, out statementKind))
                        {
                            completionContext.WordToComplete = tokenAtCursor.Text;
                            result = CompletionCompleters.CompleteStatementFlags(statementKind, completionContext.WordToComplete);
                            break;
                        }
                        break;

                    case TokenKind.DynamicKeyword:
                        {
                            DynamicKeywordStatementAst keywordAst;
                            ConfigurationDefinitionAst configureAst = GetAncestorConfigurationAstAndKeywordAst(
                                completionContext.CursorPosition, lastAst, out keywordAst);
                            Diagnostics.Assert(configureAst != null, "ConfigurationDefinitionAst should never be null");
                            bool matched = false;
                            completionContext.WordToComplete = tokenAtCursor.Text.Trim();
                            // Current token is within ConfigurationDefinitionAst or DynamicKeywordStatementAst
                            return GetResultForIdentifierInConfiguration(completionContext, configureAst, null, out matched);
                        }
                    case TokenKind.Equals:
                    case TokenKind.AtParen:
                    case TokenKind.LParen:
                        {
                            if (lastAst is AttributeAst)
                            {
                                completionContext.ReplacementIndex = replacementIndex += tokenAtCursor.Text.Length;
                                completionContext.ReplacementLength = replacementLength = 0;
                                result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
                            }
                            else
                            {
                                //
                                // Handle auto completion for enum/dependson property of DSC resource,
                                // cursor is right after '=', '(' or '@('
                                //
                                // Configuration config
                                // {
                                //     User test
                                //     {
                                //         DependsOn=|
                                //         DependsOn=@(|)
                                //         DependsOn=(|
                                //
                                bool unused;
                                result = GetResultForEnumPropertyValueOfDSCResource(completionContext, string.Empty,
                                    ref replacementIndex, ref replacementLength, out unused);
                            }
                            break;
                        }
                    default:
                        if ((tokenAtCursor.TokenFlags & TokenFlags.Keyword) != 0)
                        {
                            completionContext.WordToComplete = tokenAtCursor.Text;

                            // Handle the file name completion
                            result = CompleteFileNameAsCommand(completionContext);

                            // Handle the command name completion
                            var commandNameResult = CompletionCompleters.CompleteCommand(completionContext);
                            if (commandNameResult != null && commandNameResult.Count > 0)
                            {
                                result.AddRange(commandNameResult);
                            }
                        }
                        else
                        {
                            replacementIndex = -1;
                            replacementLength = -1;
                        }
                        break;
                }
            }
            else
            {
                IScriptPosition cursor = completionContext.CursorPosition;
                bool isCursorLineEmpty = String.IsNullOrWhiteSpace(cursor.Line);
                var tokenBeforeCursor = completionContext.TokenBeforeCursor;
                bool isLineContinuationBeforeCursor = false;
                if (tokenBeforeCursor != null)
                {
                    //
                    // Handle following scenario, cursor is in next line and after a command call,
                    // we need to skip the command call autocompletion if there is no backtick character
                    // in the end of the prevous line, since backtick means command call continues to the next line
                    //
                    // Configuration config
                    // {
                    //     User test
                    //     {
                    //         DependsOn=zzz
                    //         |
                    //
                    isLineContinuationBeforeCursor = completionContext.TokenBeforeCursor.Kind == TokenKind.LineContinuation;
                }
                bool skipAutoCompleteForCommandCall = isCursorLineEmpty && !isLineContinuationBeforeCursor;
                bool lastAstIsExpressionAst = lastAst is ExpressionAst;
                if (!isQuotedString &&
                    !skipAutoCompleteForCommandCall &&
                    (lastAst is CommandParameterAst || lastAst is CommandAst ||
                    (lastAstIsExpressionAst && lastAst.Parent is CommandAst) ||
                    (lastAstIsExpressionAst && lastAst.Parent is CommandParameterAst) ||
                    (lastAstIsExpressionAst && lastAst.Parent is ArrayLiteralAst &&
                    (lastAst.Parent.Parent is CommandAst || lastAst.Parent.Parent is CommandParameterAst))))
                {
                    completionContext.WordToComplete = string.Empty;

                    var hashTableAst = lastAst as HashtableAst;

                    // Do not do any tab completion if we have a hash table
                    // and an assignment is pending.  For cases like:
                    //   new-object System.Drawing.Point -prop @{ X=  -> Tab should not complete
                    // Note: This check works when all statements preceding the last are complete,
                    //       but if a preceding statement is incomplete this test fails because 
                    //       the Ast mixes the statements due to incomplete parsing.
                    //   e.g.,
                    //   new-object System.Drawing.Point -prop @{ X = 100; Y =      <- Incomplete line
                    //   new-object new-object System.Drawing.Point -prop @{ X =    <- Tab will yield hash properties.
                    if (hashTableAst != null &&
                        CheckForPendingAssigment(hashTableAst))
                    {
                        return result;
                    }

                    if (hashTableAst != null)
                    {
                        completionContext.ReplacementIndex = replacementIndex = completionContext.CursorPosition.Offset;
                        completionContext.ReplacementLength = replacementLength = 0;
                        result = CompletionCompleters.CompleteHashtableKey(completionContext, hashTableAst);
                    }
                    else
                    {
                        result = CompletionCompleters.CompleteCommandArgument(completionContext);
                        replacementIndex = completionContext.ReplacementIndex;
                        replacementLength = completionContext.ReplacementLength;
                    }
                }
                else if (!isQuotedString)
                {
                    //
                    // Handle completion of empty line within configuration statement
                    // Ignore the auto completion if there is a backtick character in previous line
                    //
                    bool cursorAtLineContinuation;
                    if ((tokenAtCursor != null && tokenAtCursor.Kind == TokenKind.LineContinuation) ||
                        (tokenBeforeCursor != null && tokenBeforeCursor.Kind == TokenKind.LineContinuation))
                        cursorAtLineContinuation = true;
                    else
                        cursorAtLineContinuation = false;
                    if (isCursorLineEmpty && !cursorAtLineContinuation)
                    {
                        //
                        // Handle following scenario, both Configuration and DSC resource 'User' are not complete
                        // Check Hashtable first, and then fallback to configuration
                        //
                        // Configuration config
                        // {
                        //     User test
                        //     {
                        //         DependsOn=''
                        //         |
                        result = GetResultForHashtable(completionContext);
                        if (result == null || result.Count == 0)
                        {
                            DynamicKeywordStatementAst keywordAst;
                            ConfigurationDefinitionAst configAst = GetAncestorConfigurationAstAndKeywordAst(cursor, lastAst, out keywordAst);
                            if (configAst != null)
                            {
                                bool matched;
                                result = GetResultForIdentifierInConfiguration(completionContext, configAst, keywordAst, out matched);
                            }
                        }
                    }
                    else if (completionContext.TokenAtCursor == null)
                    {
                        if (tokenBeforeCursor != null)
                        {
                            //
                            // Handle auto completion for enum/dependson property of DSC resource,
                            // cursor is after '=', ',', '(', or '@('
                            //
                            // Configuration config
                            // {
                            //     User test
                            //     {
                            //         DependsOn= |
                            //         DependsOn=@('[user]x', |)
                            //         DependsOn=@( |)
                            //         DependsOn=(|
                            //
                            switch (tokenBeforeCursor.Kind)
                            {
                                case TokenKind.Equals:
                                case TokenKind.Comma:
                                case TokenKind.AtParen:
                                    {
                                        bool unused;
                                        result = GetResultForEnumPropertyValueOfDSCResource(completionContext, string.Empty, ref replacementIndex, ref replacementLength, out unused);
                                        break;
                                    }
                                case TokenKind.LParen:
                                    if (lastAst is AttributeAst)
                                    {
                                        completionContext.ReplacementLength = replacementLength = 0;
                                        result = GetResultForAttributeArgument(completionContext, ref replacementIndex, ref replacementLength);
                                    }
                                    else
                                    {
                                        bool unused;
                                        result = GetResultForEnumPropertyValueOfDSCResource(completionContext, string.Empty,
                                            ref replacementIndex, ref replacementLength, out unused);
                                    }
                                    break;
                                default:
                                    break;
                            }
                        }
                    }

                    if (result != null && result.Count > 0)
                    {
                        completionContext.ReplacementIndex = replacementIndex = completionContext.CursorPosition.Offset;
                        completionContext.ReplacementLength = replacementLength = 0;
                    }
                    else
                    {
                        bool needFileCompletion = false;
                        if (lastAst is ErrorExpressionAst && lastAst.Parent is FileRedirectionAst)
                        {
                            // Handle file name completion after redirection operator: gps > <tab>
                            needFileCompletion = true;
                        }
                        else if (lastAst is ErrorStatementAst && CompleteAgainstSwitchFile(lastAst, completionContext.TokenBeforeCursor))
                        {
                            // Handle file name completion after "switch -file": switch -file <tab>
                            needFileCompletion = true;
                        }

                        if (needFileCompletion)
                        {
                            completionContext.WordToComplete = string.Empty;
                            result = new List<CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));

                            replacementIndex = completionContext.ReplacementIndex;
                            replacementLength = completionContext.ReplacementLength;
                        }
                    }
                }
            }

            if (result == null || result.Count == 0)
            {
                var typeAst = completionContext.RelatedAsts.OfType<TypeExpressionAst>().FirstOrDefault();
                TypeName typeNameToComplete = null;
                if (typeAst != null)
                {
                    typeNameToComplete = FindTypeNameToComplete(typeAst.TypeName, _cursorPosition);
                }
                else
                {
                    var typeConstraintAst = completionContext.RelatedAsts.OfType<TypeConstraintAst>().FirstOrDefault();
                    if (typeConstraintAst != null)
                    {
                        typeNameToComplete = FindTypeNameToComplete(typeConstraintAst.TypeName, _cursorPosition);
                    }
                }

                if (typeNameToComplete != null)
                {
                    // See if the typename to complete really is within the typename, and if so, which one, in the case of generics.

                    replacementIndex = typeNameToComplete.Extent.StartOffset;
                    replacementLength = typeNameToComplete.Extent.EndOffset - replacementIndex;
                    completionContext.WordToComplete = typeNameToComplete.FullName;
                    result = CompletionCompleters.CompleteType(completionContext);
                }
            }

            if (result == null || result.Count == 0)
            {
                result = GetResultForHashtable(completionContext);
            }

            if (result == null || result.Count == 0)
            {
                // Handle special file completion scenarios: .\+file.txt -> +<tab>
                string input = completionContext.RelatedAsts[0].Extent.Text;
                if (Regex.IsMatch(input, @"^[\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 = input;
                    result = CompleteFileNameAsCommand(completionContext);
                }
            }

            return result;
        }
예제 #29
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     return this.PipelineElements.Last<CommandBaseAst>().GetInferredType(context);
 }
예제 #30
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     yield return new PSTypeName(typeof(System.Management.Automation.ScriptBlock));
 }
예제 #31
0
        // Helper method to auto complete hashtale key
        private List<CompletionResult> GetResultForHashtable(CompletionContext completionContext)
        {
            var lastAst = completionContext.RelatedAsts.Last();
            HashtableAst tempHashtableAst = null;
            IScriptPosition cursor = completionContext.CursorPosition;
            var hashTableAst = lastAst as HashtableAst;
            if (hashTableAst != null)
            {
                // Check if the cursor within the hashtable
                if (cursor.Offset < hashTableAst.Extent.EndOffset)
                {
                    tempHashtableAst = hashTableAst;
                }
                else if (cursor.Offset == hashTableAst.Extent.EndOffset)
                {
                    // Exclude the scenario that cursor at the end of hashtable, i.e. after '}'
                    if (completionContext.TokenAtCursor == null ||
                        completionContext.TokenAtCursor.Kind != TokenKind.RCurly)
                    {
                        tempHashtableAst = hashTableAst;
                    }
                }
            }
            else
            {
                // Handle property completion on a blank line for DynamicKeyword statement
                Ast lastChildofHashtableAst;
                hashTableAst = Ast.GetAncestorHashtableAst(lastAst, out lastChildofHashtableAst);

                // Check if the hashtable within a DynamicKeyword statement
                if (hashTableAst != null)
                {
                    var keywordAst = Ast.GetAncestorAst<DynamicKeywordStatementAst>(hashTableAst);
                    if (keywordAst != null)
                    {
                        // Handle only empty line
                        if (String.IsNullOrWhiteSpace(cursor.Line))
                        {
                            // Check if the cursor outside of last child of hashtable and within the hashtable
                            if (cursor.Offset > lastChildofHashtableAst.Extent.EndOffset &&
                                cursor.Offset <= hashTableAst.Extent.EndOffset)
                            {
                                tempHashtableAst = hashTableAst;
                            }
                        }
                    }
                }
            }
            hashTableAst = tempHashtableAst;
            if (hashTableAst != null)
            {
                completionContext.ReplacementIndex = completionContext.CursorPosition.Offset;
                completionContext.ReplacementLength = 0;
                return CompletionCompleters.CompleteHashtableKey(completionContext, hashTableAst);
            }
            return null;
        }
예제 #32
0
 internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context)
 {
     return this.Expression.GetInferredType(context);
 }
예제 #33
0
        private List<CompletionResult> GetResultForEnumPropertyValueOfDSCResource(
            CompletionContext completionContext,
            string stringToComplete,
            ref int replacementIndex,
            ref int replacementLength,
            out bool shouldContinue)
        {
            shouldContinue = true;
            bool isCursorInString = completionContext.TokenAtCursor is StringToken;
            List<CompletionResult> result = null;
            var lastAst = completionContext.RelatedAsts.Last();
            Ast lastChildofHashtableAst;
            var hashTableAst = Ast.GetAncestorHashtableAst(lastAst, out lastChildofHashtableAst);
            Diagnostics.Assert(stringToComplete != null, "stringToComplete should never be null");
            // Check if the hashtable within a DynamicKeyword statement
            if (hashTableAst != null)
            {
                var keywordAst = Ast.GetAncestorAst<DynamicKeywordStatementAst>(hashTableAst);
                if (keywordAst != null)
                {
                    IScriptPosition cursor = completionContext.CursorPosition;
                    var keyValuePairWithCursor = GetHashEntryContainsCursor(cursor, hashTableAst, isCursorInString);
                    if (keyValuePairWithCursor != null)
                    {
                        var propertyNameAst = keyValuePairWithCursor.Item1 as StringConstantExpressionAst;
                        if (propertyNameAst != null)
                        {
                            DynamicKeywordProperty property;
                            if (keywordAst.Keyword.Properties.TryGetValue(propertyNameAst.Value, out property))
                            {
                                List<String> existingValues = null;
                                WildcardPattern wildcardPattern = null;
                                bool isDependsOnProperty = String.Equals(property.Name, @"DependsOn", StringComparison.OrdinalIgnoreCase);
                                bool hasNewLine = false;
                                string stringQuote = (completionContext.TokenAtCursor is StringExpandableToken) ? "\"" : "'";
                                if ((property.ValueMap != null && property.ValueMap.Count > 0) || isDependsOnProperty)
                                {
                                    shouldContinue = false;
                                    existingValues = new List<String>();
                                    if (String.Equals(property.TypeConstraint, "StringArray", StringComparison.OrdinalIgnoreCase))
                                    {
                                        var arrayAst = Ast.GetAncestorAst<ArrayLiteralAst>(lastAst);
                                        if (arrayAst != null && arrayAst.Elements.Count > 0)
                                        {
                                            foreach (ExpressionAst expression in arrayAst.Elements)
                                            {
                                                //
                                                // stringAst can be null in following case
                                                //      DependsOn='[user]x',|
                                                //
                                                var stringAst = expression as StringConstantExpressionAst;
                                                if (stringAst != null && IsCursorOutsideOfExtent(cursor, expression.Extent))
                                                {
                                                    existingValues.Add(stringAst.Value);
                                                }
                                            }
                                        }
                                    }
                                    //
                                    // Make sure only auto-complete string value in current line
                                    //
                                    stringToComplete = GetFirstLineSubString(stringToComplete, out hasNewLine);
                                    completionContext.WordToComplete = stringToComplete;
                                    replacementLength = completionContext.ReplacementLength = stringToComplete.Length;
                                    //
                                    // Calculate the replacementIndex based on cursor location (relative to the string token)
                                    //
                                    if (completionContext.TokenAtCursor is StringToken)
                                    {
                                        replacementIndex = completionContext.TokenAtCursor.Extent.StartOffset + 1;
                                    }
                                    else
                                    {
                                        replacementIndex = completionContext.CursorPosition.Offset - replacementLength;
                                    }
                                    completionContext.ReplacementIndex = replacementIndex;
                                    string matchString = stringToComplete + "*";
                                    wildcardPattern = WildcardPattern.Get(matchString, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant);
                                    result = new List<CompletionResult>();
                                }

                                Diagnostics.Assert(isCursorInString || (!hasNewLine), "hasNoQuote and hasNewLine cannot be true at the same time");
                                if (property.ValueMap != null && property.ValueMap.Count > 0)
                                {
                                    IEnumerable<string> orderedValues = property.ValueMap.Keys.OrderBy(x => x).Where(v => !existingValues.Contains(v, StringComparer.OrdinalIgnoreCase));
                                    var matchedResults = orderedValues.Where(v => wildcardPattern.IsMatch(v));
                                    if (matchedResults == null || !matchedResults.Any())
                                    {
                                        // Fallback to all allowed values
                                        matchedResults = orderedValues;
                                    }
                                    foreach (var value in matchedResults)
                                    {
                                        string completionText = isCursorInString ? value : stringQuote + value + stringQuote;
                                        if (hasNewLine)
                                            completionText = completionText + stringQuote;
                                        result.Add(new CompletionResult(
                                            completionText,
                                            value,
                                            CompletionResultType.Text,
                                            value));
                                    }
                                }
                                else if (isDependsOnProperty)
                                {
                                    var configAst = Ast.GetAncestorAst<ConfigurationDefinitionAst>(keywordAst);
                                    if (configAst != null)
                                    {
                                        var namedBlockAst = Ast.GetAncestorAst<NamedBlockAst>(keywordAst);
                                        if (namedBlockAst != null)
                                        {
                                            List<string> allResources = new List<string>();
                                            foreach (var statementAst in namedBlockAst.Statements)
                                            {
                                                var dynamicKeywordAst = statementAst as DynamicKeywordStatementAst;
                                                if (dynamicKeywordAst != null &&
                                                    dynamicKeywordAst != keywordAst &&
                                                    !String.Equals(dynamicKeywordAst.Keyword.Keyword, @"Node", StringComparison.OrdinalIgnoreCase))
                                                {
                                                    if (!String.IsNullOrEmpty(dynamicKeywordAst.ElementName))
                                                    {
                                                        StringBuilder sb = new StringBuilder("[");
                                                        sb.Append(dynamicKeywordAst.Keyword.Keyword);
                                                        sb.Append("]");
                                                        sb.Append(dynamicKeywordAst.ElementName);
                                                        var resource = sb.ToString();
                                                        if (!existingValues.Contains(resource, StringComparer.OrdinalIgnoreCase) &&
                                                            !allResources.Contains(resource, StringComparer.OrdinalIgnoreCase))
                                                        {
                                                            allResources.Add(resource);
                                                        }
                                                    }
                                                }
                                            }
                                            var matchedResults = allResources.Where(r => wildcardPattern.IsMatch(r));
                                            if (matchedResults == null || !matchedResults.Any())
                                            {
                                                // Fallback to all allowed values
                                                matchedResults = allResources;
                                            }

                                            foreach (var resource in matchedResults)
                                            {
                                                string completionText = isCursorInString ? resource : stringQuote + resource + stringQuote;
                                                if (hasNewLine)
                                                    completionText = completionText + stringQuote;
                                                result.Add(new CompletionResult(
                                                    completionText,
                                                    resource,
                                                    CompletionResultType.Text,
                                                    resource));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return result;
        }