public AssignmentStatementAst(IScriptExtent extent, ExpressionAst left, TokenKind @operator, StatementAst right, IScriptExtent errorPosition) : base(extent) { if (((left == null) || (right == null)) || (errorPosition == null)) { throw PSTraceSource.NewArgumentNullException((left == null) ? "left" : ((right == null) ? "right" : "errorPosition")); } if ((@operator.GetTraits() & TokenFlags.AssignmentOperator) == TokenFlags.None) { throw PSTraceSource.NewArgumentException("operator"); } PipelineAst ast = right as PipelineAst; if ((ast != null) && (ast.PipelineElements.Count == 1)) { CommandExpressionAst ast2 = ast.PipelineElements[0] as CommandExpressionAst; if (ast2 != null) { right = ast2; right.ClearParent(); } } this.Operator = @operator; this.Left = left; base.SetParent(left); this.Right = right; base.SetParent(right); this.ErrorPosition = errorPosition; }
public override ExpressionAst GetPureExpression() { if (this.PipelineElements.Count == 1) { CommandExpressionAst ast = this.PipelineElements[0] as CommandExpressionAst; if ((ast != null) && !ast.Redirections.Any <RedirectionAst>()) { return(ast.Expression); } } return(null); }
public System.Object VisitCommandExpression(System.Management.Automation.Language.CommandExpressionAst commandExpressionAst) { IScriptExtent mappedExtent = MapExtent(commandExpressionAst.Extent); ExpressionAst mappedExpression = _VisitExpression(commandExpressionAst.Expression); LinkedList <RedirectionAst> mappedRedirections = new LinkedList <RedirectionAst>(); foreach (RedirectionAst r in commandExpressionAst.Redirections) { mappedRedirections.AddLast(_VisitRedirection(r)); } return(new CommandExpressionAst(mappedExtent, mappedExpression, mappedRedirections)); }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return(false); }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { throw PSTraceSource.NewArgumentException("ast"); }
private StatementAst MethodDeclarationRule(Token functionNameToken, string className, bool isStaticMethod) { //G method-statement: //G new-lines:opt function-name function-parameter-declaration base-ctor-call:opt '{' script-block '}' //G //G base-ctor-call: // can be present only if function-name == className //G ':' new-lines:opt 'base' new-lines:opt parenthesized-expression new-lines:opt //G //G function-name: //G command-argument var functionName = functionNameToken.Text; List<ParameterAst> parameters; Token lParen = this.PeekToken(); IScriptExtent endErrorStatement = null; Token rParen = null; if (lParen.Kind == TokenKind.LParen) { parameters = this.FunctionParameterDeclarationRule(out endErrorStatement, out rParen); } else { this.ReportIncompleteInput(After(functionNameToken), () => ParserStrings.MissingMethodParameterList); parameters = new List<ParameterAst>(); } bool isCtor = functionName.Equals(className, StringComparison.OrdinalIgnoreCase); List<ExpressionAst> baseCtorCallParams = null; Token baseToken = null; IScriptExtent baseCallLastExtent = null; TokenizerMode oldTokenizerMode; if (isCtor && !isStaticMethod) { this.SkipNewlines(); oldTokenizerMode = _tokenizer.Mode; try { SetTokenizerMode(TokenizerMode.Signature); Token colonToken = PeekToken(); if (colonToken.Kind == TokenKind.Colon) { SkipToken(); this.SkipNewlines(); baseToken = PeekToken(); if (baseToken.Kind == TokenKind.Base) { SkipToken(); this.SkipNewlines(); lParen = PeekToken(); if (lParen.Kind == TokenKind.LParen) { SkipToken(); // we don't allow syntax // : base{ script } // as a short for for // : base( { script } ) baseCtorCallParams = InvokeParamParenListRule(lParen, out baseCallLastExtent); this.SkipNewlines(); } else { endErrorStatement = baseToken.Extent; ReportIncompleteInput(After(baseToken), () => ParserStrings.MissingMethodParameterList); } } else { endErrorStatement = colonToken.Extent; ReportIncompleteInput(After(colonToken), () => ParserStrings.MissingBaseCtorCall); } } } finally { SetTokenizerMode(oldTokenizerMode); } if (baseCtorCallParams == null) { // Assuming implicit default ctor baseCtorCallParams = new List<ExpressionAst>(); } } Token lCurly = NextToken(); if (lCurly.Kind != TokenKind.LCurly) { // ErrorRecovery: If there is no opening curly, assume it hasn't been entered yet and don't consume anything. UngetToken(lCurly); if (endErrorStatement == null) { endErrorStatement = ExtentFromFirstOf(rParen, functionNameToken); ReportIncompleteInput(After(endErrorStatement), () => ParserStrings.MissingFunctionBody); } } if (endErrorStatement != null) { return new ErrorStatementAst(ExtentOf(functionNameToken, endErrorStatement), parameters); } StatementAst baseCtorCallStatement = null; if (isCtor && !isStaticMethod) { IScriptExtent baseCallExtent; IScriptExtent baseKeywordExtent; if (baseToken != null) { baseCallExtent = ExtentOf(baseToken, baseCallLastExtent); baseKeywordExtent = baseToken.Extent; } else { baseCallExtent = PositionUtilities.EmptyExtent; baseKeywordExtent = PositionUtilities.EmptyExtent; } var invokeMemberAst = new BaseCtorInvokeMemberExpressionAst(baseKeywordExtent, baseCallExtent, baseCtorCallParams); baseCtorCallStatement = new CommandExpressionAst(invokeMemberAst.Extent, invokeMemberAst, null); } oldTokenizerMode = _tokenizer.Mode; try { SetTokenizerMode(TokenizerMode.Command); ScriptBlockAst scriptBlock = ScriptBlockRule(lCurly, false, baseCtorCallStatement); var result = new FunctionDefinitionAst(ExtentOf(functionNameToken, scriptBlock), /*isFilter:*/false, /*isWorkflow:*/false, functionNameToken, parameters, scriptBlock); return result; } finally { SetTokenizerMode(oldTokenizerMode); } }
public virtual AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return AstVisitAction.Continue; }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { commandExpressionAst.Expression.Accept(this); return null; }
/// <summary/> public virtual object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return _decorated.VisitCommandExpression(commandExpressionAst); }
public override AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst) { // allowed if the child expression is allowed return AstVisitAction.Continue; }
private AssignmentStatementAst GetAssignmentStatementAst(ExpressionAst leftExpressionAst, TokenKind tokenKind) { var expressionAst = new StringConstantExpressionAst(extent, "tmp", StringConstantType.BareWord); var commandExpressionAst = new CommandExpressionAst(extent, expressionAst, redirections); return new AssignmentStatementAst(extent, leftExpressionAst, tokenKind, commandExpressionAst, extent); }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { ExpressionAst ast = commandExpressionAst.Expression; Expression expr = this.Compile(ast); UnaryExpressionAst ast2 = ast as UnaryExpressionAst; if (((ast2 == null) || !ast2.TokenKind.HasTrait(TokenFlags.PrefixOrPostfixOperator)) && !expr.Type.Equals(typeof(void))) { return this.CallAddPipe(expr, _getCurrentPipe); } return expr; }
/// <summary/> public virtual AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst) => DefaultVisit(commandExpressionAst);
private Expression GetRedirectedExpression(CommandExpressionAst commandExpr, bool captureForInput) { MergeRedirectExprs generateRedirectExprs = null; MergeRedirectExprs exprs2 = null; List<Expression> exprs = new List<Expression>(); List<ParameterExpression> temps = new List<ParameterExpression>(); List<Expression> finallyExprs = new List<Expression>(); if (!captureForInput) { exprs.Add(this.UpdatePosition(commandExpr)); } bool flag = commandExpr.Redirections.Where<RedirectionAst>(delegate (RedirectionAst r) { if (!(r is FileRedirectionAst)) { return false; } if (r.FromStream != RedirectionStream.Output) { return (r.FromStream == RedirectionStream.All); } return true; }).Any<RedirectionAst>(); ParameterExpression item = null; SubExpressionAst expression = commandExpr.Expression as SubExpressionAst; if ((expression != null) && captureForInput) { ParameterExpression expression2 = this.NewTemp(typeof(Pipe), "oldPipe"); item = this.NewTemp(typeof(ArrayList), "arrayList"); temps.Add(item); temps.Add(expression2); exprs.Add(Expression.Assign(expression2, _getCurrentPipe)); exprs.Add(Expression.Assign(item, Expression.New(CachedReflectionInfo.ArrayList_ctor))); exprs.Add(Expression.Assign(_getCurrentPipe, Expression.New(CachedReflectionInfo.Pipe_ctor, new Expression[] { item }))); finallyExprs.Add(Expression.Assign(_getCurrentPipe, expression2)); } foreach (FileRedirectionAst ast2 in commandExpr.Redirections.OfType<FileRedirectionAst>()) { object obj2 = this.VisitFileRedirection(ast2); ParameterExpression expression3 = this.NewTemp(typeof(Pipe[]), "savedPipes"); temps.Add(expression3); ParameterExpression expression4 = this.NewTemp(typeof(FileRedirection), "fileRedirection"); temps.Add(expression4); exprs.Add(Expression.Assign(expression4, (Expression) obj2)); exprs.Add(Expression.Assign(expression3, Expression.Call(expression4, CachedReflectionInfo.FileRedirection_BindForExpression, new Expression[] { _functionContext }))); finallyExprs.Add(Expression.Call(expression4.Cast(typeof(CommandRedirection)), CachedReflectionInfo.CommandRedirection_UnbindForExpression, _functionContext, expression3)); finallyExprs.Add(Expression.Call(expression4, CachedReflectionInfo.FileRedirection_Dispose)); } Expression expression5 = null; ParenExpressionAst ast3 = commandExpr.Expression as ParenExpressionAst; if (ast3 != null) { AssignmentStatementAst pipeline = ast3.Pipeline as AssignmentStatementAst; if (pipeline != null) { if (generateRedirectExprs == null) { generateRedirectExprs = delegate (List<Expression> mergeExprs, List<Expression> mergeFinallyExprs) { this.AddMergeRedirectionExpressions(commandExpr.Redirections, temps, mergeExprs, mergeFinallyExprs); }; } expression5 = this.CompileAssignment(pipeline, generateRedirectExprs); } else { if (exprs2 == null) { exprs2 = delegate (List<Expression> mergeExprs, List<Expression> mergeFinallyExprs) { this.AddMergeRedirectionExpressions(commandExpr.Redirections, temps, mergeExprs, mergeFinallyExprs); }; } expression5 = this.CaptureAstResults(ast3.Pipeline, CaptureAstContext.Assignment, exprs2); } } else if (expression != null) { this.AddMergeRedirectionExpressions(commandExpr.Redirections, temps, exprs, finallyExprs); exprs.Add(this.Compile(expression.SubExpression)); if (item != null) { expression5 = Expression.Call(CachedReflectionInfo.PipelineOps_PipelineResult, item); } } else { this.AddMergeRedirectionExpressions(commandExpr.Redirections, temps, exprs, finallyExprs); expression5 = this.Compile(commandExpr.Expression); } if (expression5 != null) { if (!flag && captureForInput) { exprs.Add(expression5); } else { exprs.Add(this.CallAddPipe(expression5, _getCurrentPipe)); exprs.Add(ExpressionCache.AutomationNullConstant); } } if (finallyExprs.Count != 0) { return Expression.Block(temps.ToArray(), new Expression[] { Expression.TryFinally(Expression.Block(exprs), Expression.Block(finallyExprs)) }); } return Expression.Block(temps.ToArray(), exprs); }
private PipelineBaseAst PipelineRule() { List<CommandBaseAst> source = new List<CommandBaseAst>(); IScriptExtent first = null; Token token = null; bool flag = true; while (flag) { CommandBaseAst ast; ExpressionAst ast2; Token token2 = null; TokenizerMode mode = this._tokenizer.Mode; try { this.SetTokenizerMode(TokenizerMode.Expression); ast2 = this.ExpressionRule(); if (ast2 != null) { Token token3 = this.PeekToken(); if (token3.Kind.HasTrait(TokenFlags.AssignmentOperator)) { this.SkipToken(); token2 = token3; } } } finally { this.SetTokenizerMode(mode); } if (ast2 != null) { if (source.Any<CommandBaseAst>()) { this.ReportError(ast2.Extent, ParserStrings.ExpressionsMustBeFirstInPipeline, new object[0]); } if (token2 != null) { this.SkipNewlines(); StatementAst right = this.StatementRule(); if (right == null) { IScriptExtent extent2 = After(token2); this.ReportIncompleteInput(extent2, ParserStrings.ExpectedValueExpression, new object[] { token2.Kind.Text() }); right = new ErrorStatementAst(extent2, (IEnumerable<Ast>)null); } return new AssignmentStatementAst(ExtentOf((Ast)ast2, (Ast)right), ast2, token2.Kind, right, token2.Extent); } RedirectionAst[] redirections = null; RedirectionToken redirectionToken = this.PeekToken() as RedirectionToken; RedirectionAst ast4 = null; while (redirectionToken != null) { this.SkipToken(); if (redirections == null) { redirections = new RedirectionAst[7]; } IScriptExtent extent3 = null; ast4 = this.RedirectionRule(redirectionToken, redirections, ref extent3); redirectionToken = this.PeekToken() as RedirectionToken; } IScriptExtent extent = (ast4 != null) ? ExtentOf((Ast)ast2, (Ast)ast4) : ast2.Extent; ast = new CommandExpressionAst(extent, ast2, (redirections != null) ? (from r in redirections where r != null select r) : null); } else { ast = this.CommandRule(); } if (ast != null) { if (first == null) { first = ast.Extent; } source.Add(ast); } else if (source.Any<CommandBaseAst>() || (this.PeekToken().Kind == TokenKind.Pipe)) { IScriptExtent extent5 = (token != null) ? After(token) : this.PeekToken().Extent; this.ReportIncompleteInput(extent5, ParserStrings.EmptyPipeElement, new object[0]); } token = this.PeekToken(); switch (token.Kind) { case TokenKind.NewLine: case TokenKind.EndOfInput: case TokenKind.RParen: case TokenKind.RCurly: case TokenKind.Semi: { flag = false; continue; } case TokenKind.AndAnd: case TokenKind.OrOr: { this.SkipToken(); this.SkipNewlines(); this.ReportError(token.Extent, ParserStrings.InvalidEndOfLine, new object[] { token.Text }); if (this.PeekToken().Kind == TokenKind.EndOfInput) { flag = false; } continue; } case TokenKind.Pipe: { this.SkipToken(); this.SkipNewlines(); if (this.PeekToken().Kind == TokenKind.EndOfInput) { flag = false; this.ReportIncompleteInput(After(token), ParserStrings.EmptyPipeElement, new object[0]); } continue; } } this.ReportError(token.Extent, ParserStrings.UnexpectedToken, new object[] { token.Text }); flag = false; } if (source.Count == 0) { return null; } return new PipelineAst(ExtentOf(first, source[source.Count - 1]), source); }
private PipelineBaseAst PipelineRule() { //G pipeline: //G assignment-expression //G expression redirections:opt pipeline-tail:opt //G command pipeline-tail:opt //G //G assignment-expression: //G expression assignment-operator statement //G //G pipeline-tail: //G '|' new-lines:opt command //G '|' new-lines:opt command pipeline-tail var pipelineElements = new List<CommandBaseAst>(); IScriptExtent startExtent = null; Token pipeToken = null; bool scanning = true; while (scanning) { CommandBaseAst commandAst; Token assignToken = null; ExpressionAst expr; var oldTokenizerMode = _tokenizer.Mode; try { SetTokenizerMode(TokenizerMode.Expression); expr = ExpressionRule(); if (expr != null) { // We peek here because we are in expression mode, otherwise =0 will get scanned // as a single token. var token = PeekToken(); if (token.Kind.HasTrait(TokenFlags.AssignmentOperator)) { SkipToken(); assignToken = token; } } } finally { SetTokenizerMode(oldTokenizerMode); } if (expr != null) { if (pipelineElements.Count > 0) { // ErrorRecovery: this is a semantic error, so just keep parsing. ReportError(expr.Extent, () => ParserStrings.ExpressionsMustBeFirstInPipeline); } if (assignToken != null) { SkipNewlines(); StatementAst statement = StatementRule(); if (statement == null) { // ErrorRecovery: we are very likely at EOF because pretty much anything should result in some // pipeline, so just keep parsing. IScriptExtent errorExtent = After(assignToken); ReportIncompleteInput(errorExtent, () => ParserStrings.ExpectedValueExpression, assignToken.Kind.Text()); statement = new ErrorStatementAst(errorExtent); } return new AssignmentStatementAst(ExtentOf(expr, statement), expr, assignToken.Kind, statement, assignToken.Extent); } RedirectionAst[] redirections = null; var redirectionToken = PeekToken() as RedirectionToken; RedirectionAst lastRedirection = null; while (redirectionToken != null) { SkipToken(); if (redirections == null) { redirections = new RedirectionAst[CommandBaseAst.MaxRedirections]; } IScriptExtent unused = null; lastRedirection = RedirectionRule(redirectionToken, redirections, ref unused); redirectionToken = PeekToken() as RedirectionToken; } var exprExtent = lastRedirection != null ? ExtentOf(expr, lastRedirection) : expr.Extent; commandAst = new CommandExpressionAst(exprExtent, expr, redirections != null ? redirections.Where(r => r != null) : null); } else { commandAst = (CommandAst)CommandRule(forDynamicKeyword: false); } if (commandAst != null) { if (startExtent == null) { startExtent = commandAst.Extent; } pipelineElements.Add(commandAst); } else if (pipelineElements.Count > 0 || PeekToken().Kind == TokenKind.Pipe) { // ErrorRecovery: just fall through // If the first pipe element is null, the position points to the pipe (ideally it would // point before, but the pipe could be the first character), otherwise the empty element // is after the pipe character. IScriptExtent errorPosition = pipeToken != null ? After(pipeToken) : PeekToken().Extent; ReportIncompleteInput(errorPosition, () => ParserStrings.EmptyPipeElement); } pipeToken = PeekToken(); switch (pipeToken.Kind) { case TokenKind.Semi: case TokenKind.NewLine: case TokenKind.RParen: case TokenKind.RCurly: case TokenKind.EndOfInput: scanning = false; continue; case TokenKind.Pipe: SkipToken(); SkipNewlines(); if (PeekToken().Kind == TokenKind.EndOfInput) { scanning = false; ReportIncompleteInput(After(pipeToken), () => ParserStrings.EmptyPipeElement); } break; case TokenKind.AndAnd: case TokenKind.OrOr: // Parse in a manner similar to a pipe, but issue an error (for now, but should implement this for V3.) SkipToken(); SkipNewlines(); ReportError(pipeToken.Extent, () => ParserStrings.InvalidEndOfLine, pipeToken.Text); if (PeekToken().Kind == TokenKind.EndOfInput) { scanning = false; } break; default: // ErrorRecovery: don't eat the token, assume it belongs to something else. ReportError(pipeToken.Extent, () => ParserStrings.UnexpectedToken, pipeToken.Text); scanning = false; break; } } if (pipelineElements.Count == 0) { return null; } return new PipelineAst(ExtentOf(startExtent, pipelineElements[pipelineElements.Count - 1]), pipelineElements); }
PipelineBaseAst BuildPipelineExpressionAst(ParseTreeNode parseTreeNode) { VerifyTerm(parseTreeNode, this._grammar._pipeline_expression); var commandExpressionAst = new CommandExpressionAst( new ScriptExtent(parseTreeNode.ChildNodes[0]), BuildExpressionAst(parseTreeNode.ChildNodes[0]), null ); if (parseTreeNode.ChildNodes.Count == 1) { return new PipelineAst( new ScriptExtent(parseTreeNode), commandExpressionAst ); } if (parseTreeNode.ChildNodes.Count == 2 && parseTreeNode.ChildNodes[1].Term == this._grammar.pipeline_tails) { var pipelineTail = GetPipelineTailsCommandList(parseTreeNode.ChildNodes[1]).ToList(); pipelineTail.Insert(0, commandExpressionAst); return new PipelineAst(new ScriptExtent(parseTreeNode), pipelineTail); } throw new NotImplementedException(parseTreeNode.ToString()); }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { throw new UnexpectedElementException(); }
public override AstVisitAction VisitCommandExpression(CommandExpressionAst ast) { return CheckParent(ast); }
public override AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return(AstVisitAction.Continue); }
/// <summary> /// Visit command expression /// </summary> /// <param name="commandExpressionAst"></param> /// <returns></returns> public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { if (commandExpressionAst == null) return null; commandExpressionAst.Expression.Visit(this.Decorator); return null; }
public override AstVisitAction VisitCommandExpression(CommandExpressionAst ast) { return this.Check(ast); }
public override AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst) { throw new Exception("Unreachable, should be part of a pipeline. Please report this!"); }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { commandExpressionAst.Expression.Accept(this); return(null); }
public override AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst) { // just iterate over children return base.VisitCommandExpression(commandExpressionAst); }
public override AstVisitAction VisitCommandExpression(CommandExpressionAst ast) { return(Check(ast)); }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return AutomationNull.Value; }
/// <summary/> public virtual object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return null; }
/// <summary/> public virtual object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return(null); }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return false; }
// A redirected expression requires extra work because there is no CommandProcessor or PipelineProcessor // created to pass the redirections to, so we must change the redirections in the ExecutionContext // directly. private Expression GetRedirectedExpression(CommandExpressionAst commandExpr, bool captureForInput) { // Generate code like: // // try { // oldPipe = funcContext._outputPipe; // funcContext._outputPipe = outputFileRedirection.BindForExpression(executionContext); // tmp = nonOutputFileRedirection.BindForExpression(executionContext); // tmp1 = mergingRedirection.BindForExpression(executionContext, funcContext._outputPipe); // funcContext._outputPipe.Add(expression...); // } finally { // nonOutputFileRedirection.UnbindForExpression(tmp); // mergingRedirection.UnbindForExpression(tmp1); // nonOutputFileRedirection.Dispose(); // outputFileRedirection.Dispose(); // funcContext._outputPipe = oldPipe; // } // // In the above psuedo-code, any of {outputFileRedirection, nonOutputFileRedirection, mergingRedirection} may // not exist, but the order is preserved, so that file redirections go before merging redirections (so that // funcContext._outputPipe has the correct value when setting up merging.) var exprs = new List<Expression>(); var temps = new List<ParameterExpression>(); var finallyExprs = new List<Expression>(); // For the output stream, we change funcContext._outputPipe so all output goes to the file. // Currently output can only be redirected to a file stream. bool outputRedirected = commandExpr.Redirections.Any(r => r is FileRedirectionAst && (r.FromStream == RedirectionStream.Output || r.FromStream == RedirectionStream.All)); ParameterExpression resultList = null; ParameterExpression oldPipe = null; var subExpr = commandExpr.Expression as SubExpressionAst; if (subExpr != null && captureForInput) { oldPipe = NewTemp(typeof(Pipe), "oldPipe"); resultList = NewTemp(typeof(List<object>), "resultList"); temps.Add(resultList); temps.Add(oldPipe); exprs.Add(Expression.Assign(oldPipe, s_getCurrentPipe)); exprs.Add(Expression.Assign(resultList, Expression.New(CachedReflectionInfo.ObjectList_ctor))); exprs.Add(Expression.Assign(s_getCurrentPipe, Expression.New(CachedReflectionInfo.Pipe_ctor, resultList))); exprs.Add(Expression.Call(oldPipe, CachedReflectionInfo.Pipe_SetVariableListForTemporaryPipe, s_getCurrentPipe)); } // We must generate the code for output redirection to a file before any merging redirections // because merging redirections will use funcContext._outputPipe as the value to merge to, so defer merging // redirections until file redirections are done. foreach (var fileRedirectionAst in commandExpr.Redirections.OfType<FileRedirectionAst>()) { // This will simply return a Linq.Expression representing the redirection. var compiledRedirection = VisitFileRedirection(fileRedirectionAst); // For non-output streams (error, warning, etc.) we must save the old stream so it can be restored. // The savedPipe variable is used only for setting funcContext._outputPipe for redirecting Output to file. // The savedPipes variable is used for restoring non-output streams (error, warning, etc.). var savedPipes = NewTemp(typeof(Pipe[]), "savedPipes"); temps.Add(savedPipes); var redirectionExpr = NewTemp(typeof(FileRedirection), "fileRedirection"); temps.Add(redirectionExpr); exprs.Add(Expression.Assign(redirectionExpr, (Expression)compiledRedirection)); /* if (fileRedirectionAst.FromStream != RedirectionStream.Output && !(redirectionExpr is ConstantExpression)) { // We'll be reusing redirectionExpr, it's not constant, so save it in a temp. var temp = Expression.Variable(redirectionExpr.Type); temps.Add(temp); exprs.Add(Expression.Assign(temp, redirectionExpr)); redirectionExpr = temp; } */ exprs.Add(Expression.Assign( savedPipes, Expression.Call(redirectionExpr, CachedReflectionInfo.FileRedirection_BindForExpression, _functionContext))); finallyExprs.Add(Expression.Call(redirectionExpr.Cast(typeof(CommandRedirection)), CachedReflectionInfo.CommandRedirection_UnbindForExpression, _functionContext, savedPipes)); // In either case, we must dispose of the redirection or file handles won't get released. finallyExprs.Add(Expression.Call(redirectionExpr, CachedReflectionInfo.FileRedirection_Dispose)); } Expression result = null; var parenExpr = commandExpr.Expression as ParenExpressionAst; if (parenExpr != null) { // Special processing for paren expressions that capture output. // Insert any merge redirect expressions during paren expression compilation. var assignmentStatementAst = parenExpr.Pipeline as AssignmentStatementAst; if (assignmentStatementAst != null) { result = CompileAssignment( assignmentStatementAst, (mergeExprs, mergeFinallyExprs) => AddMergeRedirectionExpressions(commandExpr.Redirections, temps, mergeExprs, mergeFinallyExprs)); } else { bool shouldPreserveResultInCaseofException = parenExpr.ShouldPreserveOutputInCaseOfException(); result = CaptureAstResults( parenExpr.Pipeline, shouldPreserveResultInCaseofException ? CaptureAstContext.AssignmentWithResultPreservation : CaptureAstContext.AssignmentWithoutResultPreservation, (mergeExprs, mergeFinallyExprs) => AddMergeRedirectionExpressions(commandExpr.Redirections, temps, mergeExprs, mergeFinallyExprs)); } } else if (subExpr != null) { // Include any redirection merging. AddMergeRedirectionExpressions(commandExpr.Redirections, temps, exprs, finallyExprs); exprs.Add(Compile(subExpr.SubExpression)); if (resultList != null) { // If there is no resultList, we wrote our results of the subexpression directly to the pipe // instead of being collected to be written here. result = Expression.Call(CachedReflectionInfo.PipelineOps_PipelineResult, resultList); } } else { // Include any redirection merging. AddMergeRedirectionExpressions(commandExpr.Redirections, temps, exprs, finallyExprs); result = Compile(commandExpr.Expression); } if (result != null) { if (!outputRedirected && captureForInput) { // If we are capturing the input (for code like: $foo.Bar() 2>&1 | downstream), then we must // capture the expression results, unless output was redirected to a file because in that case, // the output can go straight to a file. exprs.Add(result); } else { exprs.Add(CallAddPipe(result, s_getCurrentPipe)); // Make sure the result of the expression we return is AutomationNull.Value. exprs.Add(ExpressionCache.AutomationNullConstant); } } if (oldPipe != null) { // If a temporary pipe was created at the beginning, we should restore the original pipe in the // very end of the finally block. Otherwise, _getCurrentPipe may be messed up by the following // file redirection unbind operation. // For example: // function foo // { // [cmdletbinding()] // param() // $(gcm NoExist) > test.txt | % { $_ } ## file redirect with new temp pipe // "hello" // } // before this change, running 'foo' will not write out 'hello'. finallyExprs.Add(Expression.Assign(s_getCurrentPipe, oldPipe)); } if (finallyExprs.Count != 0) { return Expression.Block(temps.ToArray(), Expression.TryFinally(Expression.Block(exprs), Expression.Block(finallyExprs))); } return Expression.Block(temps.ToArray(), exprs); }
/// <summary/> public virtual AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return(AstVisitAction.Continue); }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { var child = commandExpressionAst.Expression; var expr = Compile(child); var unary = child as UnaryExpressionAst; if ((unary != null && unary.TokenKind.HasTrait(TokenFlags.PrefixOrPostfixOperator)) || expr.Type == typeof(void)) { return expr; } return CallAddPipe(expr, s_getCurrentPipe); }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return(AutomationNull.Value); }
public override AstVisitAction VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return AstVisitAction.Continue; }
public void Setup() { this._commandExpressionAst = ParseStatement("'PS> '") .PipelineElements[0]; this._stringConstantExpressionAst = (StringConstantExpressionAst)this._commandExpressionAst.Expression; }
public object VisitCommandExpression(CommandExpressionAst commandExpressionAst) { return Visit(commandExpressionAst.Expression); }