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); } } }
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; }
internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context) { if (this.Value == null) { yield break; } yield return new PSTypeName(this.Value.GetType()); }
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); } }
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); }
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; } } }
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; } } }
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; } }
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; } } }
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; } } }
internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context) { return this.NestedAst.SelectMany(x => x.GetInferredType(context)); }
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; }
internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context) { yield return new PSTypeName(typeof(object[])); }
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; }
internal List <CompletionResult> GetResultHelper(CompletionContext completionContext, out int replacementIndex, out int replacementLength, bool isQuotedString) { replacementIndex = -1; replacementLength = -1; Token tokenAtCursor = completionContext.TokenAtCursor; Ast lastAst = completionContext.RelatedAsts.Last <Ast>(); List <CompletionResult> list = null; if (tokenAtCursor == null) { if (!isQuotedString && (((((lastAst is CommandParameterAst) || (lastAst is CommandAst)) || ((lastAst is ExpressionAst) && (lastAst.Parent is CommandAst))) || ((lastAst is ExpressionAst) && (lastAst.Parent is CommandParameterAst))) || (((lastAst is ExpressionAst) && (lastAst.Parent is ArrayLiteralAst)) && ((lastAst.Parent.Parent is CommandAst) || (lastAst.Parent.Parent is CommandParameterAst))))) { completionContext.WordToComplete = string.Empty; HashtableAst hashtableAst = lastAst as HashtableAst; if (hashtableAst != null) { completionContext.ReplacementIndex = replacementIndex = completionContext.CursorPosition.Offset; completionContext.ReplacementLength = replacementLength = 0; list = CompletionCompleters.CompleteHashtableKey(completionContext, hashtableAst); } else { list = CompletionCompleters.CompleteCommandArgument(completionContext); replacementIndex = completionContext.ReplacementIndex; replacementLength = completionContext.ReplacementLength; } } else if (!isQuotedString) { bool flag = false; if ((lastAst is ErrorExpressionAst) && (lastAst.Parent is FileRedirectionAst)) { flag = true; } else if ((lastAst is ErrorStatementAst) && CompleteAgainstSwitchFile(lastAst, completionContext.TokenBeforeCursor)) { flag = true; } if (flag) { completionContext.WordToComplete = string.Empty; list = new List <CompletionResult>(CompletionCompleters.CompleteFilename(completionContext)); replacementIndex = completionContext.ReplacementIndex; replacementLength = completionContext.ReplacementLength; } } } else { TokenKind kind; replacementIndex = tokenAtCursor.Extent.StartScriptPosition.Offset; replacementLength = tokenAtCursor.Extent.EndScriptPosition.Offset - replacementIndex; completionContext.ReplacementIndex = replacementIndex; completionContext.ReplacementLength = replacementLength; switch (tokenAtCursor.Kind) { case TokenKind.ColonColon: case TokenKind.Dot: replacementIndex += tokenAtCursor.Text.Length; replacementLength = 0; list = CompletionCompleters.CompleteMember(completionContext, tokenAtCursor.Kind == TokenKind.ColonColon); goto Label_05DC; case TokenKind.Multiply: case TokenKind.Identifier: case TokenKind.Generic: list = this.GetResultForIdentifier(completionContext, ref replacementIndex, ref replacementLength, isQuotedString); goto Label_05DC; case TokenKind.Minus: if (CompleteOperator(tokenAtCursor, lastAst)) { list = CompletionCompleters.CompleteOperator(""); } else if (CompleteAgainstStatementFlags(completionContext.RelatedAsts[0], null, tokenAtCursor, out kind)) { completionContext.WordToComplete = tokenAtCursor.Text; list = CompletionCompleters.CompleteStatementFlags(kind, completionContext.WordToComplete); } goto Label_05DC; case TokenKind.Redirection: if ((lastAst is ErrorExpressionAst) && (lastAst.Parent is FileRedirectionAst)) { completionContext.WordToComplete = string.Empty; completionContext.ReplacementIndex = replacementIndex += tokenAtCursor.Text.Length; completionContext.ReplacementLength = replacementLength = 0; list = new List <CompletionResult>(CompletionCompleters.CompleteFilename(completionContext)); } goto Label_05DC; case TokenKind.Variable: case TokenKind.SplattedVariable: completionContext.WordToComplete = ((VariableToken)tokenAtCursor).VariablePath.UserPath; list = CompletionCompleters.CompleteVariable(completionContext); goto Label_05DC; case TokenKind.Parameter: if (!isQuotedString) { completionContext.WordToComplete = tokenAtCursor.Text; CommandAst parent = lastAst.Parent as CommandAst; if ((!(lastAst is StringConstantExpressionAst) || (parent == null)) || (parent.CommandElements.Count != 1)) { if (CompleteAgainstStatementFlags(null, lastAst, null, out kind)) { list = CompletionCompleters.CompleteStatementFlags(kind, completionContext.WordToComplete); } else if (CompleteOperator(tokenAtCursor, lastAst)) { list = CompletionCompleters.CompleteOperator(completionContext.WordToComplete); } else if (completionContext.WordToComplete.EndsWith(":", StringComparison.Ordinal)) { replacementIndex = tokenAtCursor.Extent.EndScriptPosition.Offset; replacementLength = 0; completionContext.WordToComplete = string.Empty; list = CompletionCompleters.CompleteCommandArgument(completionContext); } else { list = CompletionCompleters.CompleteCommandParameter(completionContext); } } else { list = CompleteFileNameAsCommand(completionContext); } } goto Label_05DC; case TokenKind.Number: if ((lastAst is ConstantExpressionAst) && (((lastAst.Parent is CommandAst) || (lastAst.Parent is CommandParameterAst)) || ((lastAst.Parent is ArrayLiteralAst) && ((lastAst.Parent.Parent is CommandAst) || (lastAst.Parent.Parent is CommandParameterAst))))) { completionContext.WordToComplete = tokenAtCursor.Text; list = CompletionCompleters.CompleteCommandArgument(completionContext); replacementIndex = completionContext.ReplacementIndex; replacementLength = completionContext.ReplacementLength; } goto Label_05DC; case TokenKind.Comment: if (!isQuotedString) { completionContext.WordToComplete = tokenAtCursor.Text; list = CompletionCompleters.CompleteComment(completionContext); } goto Label_05DC; case TokenKind.StringLiteral: case TokenKind.StringExpandable: list = this.GetResultForString(completionContext, ref replacementIndex, ref replacementLength, isQuotedString); goto Label_05DC; case TokenKind.RBracket: if (lastAst is TypeExpressionAst) { TypeExpressionAst targetExpr = (TypeExpressionAst)lastAst; List <CompletionResult> results = new List <CompletionResult>(); CompletionCompleters.CompleteMemberHelper(true, "*", targetExpr, completionContext, results); if (results.Count > 0) { replacementIndex++; replacementLength = 0; list = (from entry in results let completionText = TokenKind.ColonColon.Text() + entry.CompletionText select new CompletionResult(completionText, entry.ListItemText, entry.ResultType, entry.ToolTip)).ToList <CompletionResult>(); } } goto Label_05DC; case TokenKind.Comma: if ((lastAst is ErrorExpressionAst) && ((lastAst.Parent is CommandAst) || (lastAst.Parent is CommandParameterAst))) { replacementIndex += replacementLength; replacementLength = 0; list = CompletionCompleters.CompleteCommandArgument(completionContext); } goto Label_05DC; } if ((tokenAtCursor.TokenFlags & TokenFlags.Keyword) != TokenFlags.None) { completionContext.WordToComplete = tokenAtCursor.Text; list = CompleteFileNameAsCommand(completionContext); List <CompletionResult> collection = CompletionCompleters.CompleteCommand(completionContext); if ((collection != null) && (collection.Count > 0)) { list.AddRange(collection); } } else { replacementIndex = -1; replacementLength = -1; } } Label_05DC: if ((list == null) || (list.Count == 0)) { TypeExpressionAst ast5 = completionContext.RelatedAsts.OfType <TypeExpressionAst>().FirstOrDefault <TypeExpressionAst>(); TypeName name = null; if (ast5 != null) { name = FindTypeNameToComplete(ast5.TypeName, this._cursorPosition); } else { TypeConstraintAst ast6 = completionContext.RelatedAsts.OfType <TypeConstraintAst>().FirstOrDefault <TypeConstraintAst>(); if (ast6 != null) { name = FindTypeNameToComplete(ast6.TypeName, this._cursorPosition); } } if (name != null) { replacementIndex = name.Extent.StartOffset; replacementLength = name.Extent.EndOffset - replacementIndex; completionContext.WordToComplete = name.FullName; list = CompletionCompleters.CompleteType(completionContext, "", ""); } } if ((list == null) || (list.Count == 0)) { HashtableAst ast7 = lastAst as HashtableAst; if (ast7 != null) { completionContext.ReplacementIndex = replacementIndex = completionContext.CursorPosition.Offset; completionContext.ReplacementLength = replacementLength = 0; list = CompletionCompleters.CompleteHashtableKey(completionContext, ast7); } } if ((list == null) || (list.Count == 0)) { string text = completionContext.RelatedAsts[0].Extent.Text; if ((Regex.IsMatch(text, @"^[\S]+$") && (completionContext.RelatedAsts.Count > 0)) && (completionContext.RelatedAsts[0] is ScriptBlockAst)) { replacementIndex = completionContext.RelatedAsts[0].Extent.StartScriptPosition.Offset; replacementLength = completionContext.RelatedAsts[0].Extent.EndScriptPosition.Offset - replacementIndex; completionContext.WordToComplete = text; list = CompleteFileNameAsCommand(completionContext); } } return(list); }
private 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); }
internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context) { return Ast.EmptyPSTypeNameArray; }
/// <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; }
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; }
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; }
/// <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; }
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; }
internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context) { return this.Statements.SelectMany(ast => ast.GetInferredType(context)); }
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; }
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; }
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); }
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; }
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; }
internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context) { return this.PipelineElements.Last<CommandBaseAst>().GetInferredType(context); }
internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context) { yield return new PSTypeName(typeof(System.Management.Automation.ScriptBlock)); }
// 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; }
internal override IEnumerable<PSTypeName> GetInferredType(CompletionContext context) { return this.Expression.GetInferredType(context); }
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; }