private new RemoteLinq.SwitchCase VisitSwitchCase(SystemLinq.SwitchCase switchCase) { var body = Visit(switchCase.Body).Unwrap(); var testValues = switchCase.TestValues.Select(Visit).Select(Unwrap).ToList(); return(new RemoteLinq.SwitchCase(body, testValues)); }
internal static SwitchCase Serialize(E.SwitchCase @case) { return(new SwitchCase() { TestValues = @case.TestValues.Select(Node.Serialize).ToArray(), Body = Node.Serialize(@case.Body), }); }
protected override MSAst.SwitchCase VisitSwitchCase(MSAst.SwitchCase node) { _insideConditionalBlock = true; try { return(base.VisitSwitchCase(node)); } finally { _insideConditionalBlock = false; } }
protected override SwitchCase VisitSwitchCase(SwitchCase node) { throw new NotSupportedException(); }
public SwitchCaseProxy(SwitchCase node) { _node = node; }
private Func<string, Tuple<IJsonSerializerInternal, int>> GetGetSerializerAndArgIndexFunc(ParameterInfo[] parameters) { var propertyNameParameter = Expression.Parameter(typeof(string), "propertyName"); var switchCases = new SwitchCase[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { var serializer = JsonSerializerFactory.GetSerializer(parameters[i].ParameterType, _encrypt, _mappings, _shouldUseAttributeDefinedInInterface); var serializerAndArgIndex = Tuple.Create(serializer, i); var matchingProperties = _type.GetProperties().Where(p => p.Name.Equals(parameters[i].Name, StringComparison.OrdinalIgnoreCase)).ToList(); var switchLabel = matchingProperties.Count == 1 ? matchingProperties[0].GetName(_shouldUseAttributeDefinedInInterface) : parameters[i].Name; switchCases[i] = Expression.SwitchCase( Expression.Constant(serializerAndArgIndex), Expression.Constant(switchLabel)); } var defaultCase = Expression.Constant(null, typeof(Tuple<IJsonSerializerInternal, int>)); var switchExpression = Expression.Switch(propertyNameParameter, defaultCase, switchCases); var getSerializerAndArgIndexLambda = Expression.Lambda<Func<string, Tuple<IJsonSerializerInternal, int>>>( switchExpression, propertyNameParameter); var getSerializerAndArgIndex = getSerializerAndArgIndexLambda.Compile(); return getSerializerAndArgIndex; }
public virtual bool IsEvaluatableSwitchCase (SwitchCase node) { ArgumentUtility.CheckNotNull ("node", node); return true; }
protected override SwitchCase VisitSwitchCase(SwitchCase node) { foreach (var value in node.TestValues) { this.Write("case "); this.Visit(value); this.WriteLine(":"); } using (this.AcquireIndentationContext(BraceLanguageStyleIndentationOptions.Default)) { this.Visit(node.Body); this.WriteLine("break;"); } return node; }
/// <summary> /// Visits the children of the <see cref="SwitchCase"/>. /// </summary> /// <param name="node">The expression to visit.</param> /// <returns>The modified expression, if it or any subexpression was modified; /// otherwise, returns the original expression.</returns> protected virtual SwitchCase VisitSwitchCase(SwitchCase node) { return(node.Update(Visit(node.TestValues), Visit(node.Body))); }
private void CompileStatementListWithTraps(ReadOnlyCollection<StatementAst> statements, ReadOnlyCollection<TrapStatementAst> traps, List<Expression> exprs, List<ParameterExpression> temps) { if (statements.Count == 0) { exprs.Add(ExpressionCache.Empty); return; } var originalExprs = exprs; Expression handlerInScope; ParameterExpression oldActiveHandler; ParameterExpression trapHandlersPushed; if (traps != null) { // If the statement block has any traps, we'll generate code like: // try { // oldActiveHandler = executionContext.PropagateExceptionsToEnclosingStatementBlock; // executionContext.PropagateExceptionsToEnclosingStatementBlock = true; // functionContext.PushTrapHandlers( // new Type[] { trapTypes }, // new Action<FunctionContext>[] { trapDelegates }, // new Type[] { trapLocalTupleTypes }); // trapHandlersPushed = true // // statements // } finally { // executionContext.PropagateExceptionsToEnclosingStatementBlock = oldActiveHandler; // if (trapHandlersPushed) { // functionContext.PopTrapHandlers() // } // } // // We use a runtime check on popping because in some rare cases, PushTrapHandlers might not // get called (e.g. if a trap handler specifies a type that doesn't exist, like trap [baddtype]{}). // We don't want to pop if we didn't push. exprs = new List<Expression>(); handlerInScope = Expression.Property(_executionContextParameter, CachedReflectionInfo.ExecutionContext_ExceptionHandlerInEnclosingStatementBlock); oldActiveHandler = NewTemp(typeof(bool), "oldActiveHandler"); exprs.Add(Expression.Assign(oldActiveHandler, handlerInScope)); exprs.Add(Expression.Assign(handlerInScope, ExpressionCache.Constant(true))); var trapTypes = new List<Expression>(); var trapDelegates = new List<Action<FunctionContext>>(); var trapTupleType = new List<Type>(); for (int index = 0; index < traps.Count; index++) { var trap = traps[index]; trapTypes.Add(trap.TrapType != null ? CompileTypeName(trap.TrapType.TypeName, trap.TrapType.Extent) : ExpressionCache.CatchAllType); var tuple = CompileTrap(trap); trapDelegates.Add(tuple.Item1); trapTupleType.Add(tuple.Item2); } exprs.Add(Expression.Call(_functionContext, CachedReflectionInfo.FunctionContext_PushTrapHandlers, Expression.NewArrayInit(typeof(Type), trapTypes), Expression.Constant(trapDelegates.ToArray()), Expression.Constant(trapTupleType.ToArray()))); trapHandlersPushed = NewTemp(typeof(bool), "trapHandlersPushed"); exprs.Add(Expression.Assign(trapHandlersPushed, ExpressionCache.Constant(true))); _trapNestingCount += 1; } else { oldActiveHandler = null; handlerInScope = null; trapHandlersPushed = null; if (_trapNestingCount > 0) { // If this statement block has no traps, but a parent block does, we need to make sure that process the // trap at the correct level in case we continue. For example: // trap { continue } // if (1) { // throw 1 // "Shouldn't continue here" // } // "Should continue here" // In this example, the trap just continues, but we want to continue after the 'if' statement, not after // the 'throw' statement. // We push null onto the active trap handlers to let ExceptionHandlingOps.CheckActionPreference know it // shouldn't process traps (but should still query the user if appropriate), and just rethrow so we can // unwind to the block with the trap. exprs = new List<Expression>(); exprs.Add(Expression.Call(_functionContext, CachedReflectionInfo.FunctionContext_PushTrapHandlers, ExpressionCache.NullTypeArray, ExpressionCache.NullDelegateArray, ExpressionCache.NullTypeArray)); trapHandlersPushed = NewTemp(typeof(bool), "trapHandlersPushed"); exprs.Add(Expression.Assign(trapHandlersPushed, ExpressionCache.Constant(true))); } } _stmtCount += statements.Count; // If there is a single statement, we just wrap it in try/catch (to handle traps and/or prompting based on // $ErrorActionPreference. // // If there are multiple statements, we could wrap each statement in try/catch, but it's more efficient // to have a single try/catch around the entire block. // // The interpreter handles a large number or try/catches fine, but the JIT fails miserably because it uses // an exponential algorithm. // // Because a trap or user prompting can have us stop the erroneous statement, but continue to the next // statement, we need to generate code like this: // // dispatchIndex = 0; // DispatchNextStatementTarget: // try { // switch (dispatchIndex) { // case 0: goto L0; // case 1: goto L1; // case 2: goto L2; // } // L0: dispatchIndex = 1; // statement1; // L1: dispatchIndex = 2; // statement2; // } catch (FlowControlException) { // throw; // } catch (Exception e) { // ExceptionHandlingOps.CheckActionPreference(functionContext, e); // goto DispatchNextStatementTarget; // } // L2: // // This approach makes JIT possible (but still slow) for large functions and it speeds up the light // compile (interpreter compile) by about 80%. if (statements.Count == 1) { var exprList = new List<Expression>(3); CompileTrappableExpression(exprList, statements[0]); exprList.Add(ExpressionCache.Empty); var expr = Expression.TryCatch(Expression.Block(exprList), _stmtCatchHandlers); exprs.Add(expr); } else { var switchCases = new SwitchCase[statements.Count + 1]; var dispatchTargets = new LabelTarget[statements.Count + 1]; for (int i = 0; i <= statements.Count; i++) { dispatchTargets[i] = Expression.Label(); switchCases[i] = Expression.SwitchCase(Expression.Goto(dispatchTargets[i]), ExpressionCache.Constant(i)); } var dispatchIndex = Expression.Variable(typeof(int), "stmt"); temps.Add(dispatchIndex); exprs.Add(Expression.Assign(dispatchIndex, ExpressionCache.Constant(0))); var dispatchNextStatementTarget = Expression.Label(); exprs.Add(Expression.Label(dispatchNextStatementTarget)); var tryBodyExprs = new List<Expression>(); tryBodyExprs.Add(Expression.Switch(dispatchIndex, switchCases)); for (int i = 0; i < statements.Count; i++) { tryBodyExprs.Add(Expression.Label(dispatchTargets[i])); tryBodyExprs.Add(Expression.Assign(dispatchIndex, ExpressionCache.Constant(i + 1))); CompileTrappableExpression(tryBodyExprs, statements[i]); } tryBodyExprs.Add(ExpressionCache.Empty); var exception = Expression.Variable(typeof(Exception), "exception"); var callCheckActionPreference = Expression.Call( CachedReflectionInfo.ExceptionHandlingOps_CheckActionPreference, Compiler._functionContext, exception); var catchAll = Expression.Catch( exception, Expression.Block(callCheckActionPreference, Expression.Goto(dispatchNextStatementTarget))); var expr = Expression.TryCatch(Expression.Block(tryBodyExprs), new CatchBlock[] { s_catchFlowControl, catchAll }); exprs.Add(expr); exprs.Add(Expression.Label(dispatchTargets[statements.Count])); } if (_trapNestingCount > 0) { var parameterExprs = new List<ParameterExpression>(); var finallyBlockExprs = new List<Expression>(); if (oldActiveHandler != null) { parameterExprs.Add(oldActiveHandler); finallyBlockExprs.Add(Expression.Assign(handlerInScope, oldActiveHandler)); } parameterExprs.Add(trapHandlersPushed); finallyBlockExprs.Add( Expression.IfThen(trapHandlersPushed, Expression.Call(_functionContext, CachedReflectionInfo.FunctionContext_PopTrapHandlers))); originalExprs.Add( Expression.Block(parameterExprs, Expression.TryFinally(Expression.Block(exprs), Expression.Block(finallyBlockExprs)))); } if (traps != null) { _trapNestingCount -= 1; } }
private void CompileStatementListWithTraps(ReadOnlyCollection<StatementAst> statements, ReadOnlyCollection<TrapStatementAst> traps, List<Expression> exprs, List<ParameterExpression> temps) { if (statements.Count == 0) { exprs.Add(ExpressionCache.Empty); } else { Expression expression; ParameterExpression expression2; ParameterExpression expression3; List<Expression> list = exprs; if (traps != null) { exprs = new List<Expression>(); expression = Expression.Property(_executionContextParameter, CachedReflectionInfo.ExecutionContext_ExceptionHandlerInEnclosingStatementBlock); expression2 = this.NewTemp(typeof(bool), "oldActiveHandler"); exprs.Add(Expression.Assign(expression2, expression)); exprs.Add(Expression.Assign(expression, ExpressionCache.Constant(true))); List<Expression> initializers = new List<Expression>(); List<Action<FunctionContext>> list3 = new List<Action<FunctionContext>>(); List<Type> list4 = new List<Type>(); foreach (TrapStatementAst ast in traps) { initializers.Add((ast.TrapType != null) ? this.CompileTypeName(ast.TrapType.TypeName) : ExpressionCache.CatchAllType); Tuple<Action<FunctionContext>, Type> tuple = this.CompileTrap(ast); list3.Add(tuple.Item1); list4.Add(tuple.Item2); } exprs.Add(Expression.Call(_functionContext, CachedReflectionInfo.FunctionContext_PushTrapHandlers, Expression.NewArrayInit(typeof(Type), initializers), Expression.Constant(list3.ToArray()), Expression.Constant(list4.ToArray()))); expression3 = this.NewTemp(typeof(bool), "trapHandlersPushed"); exprs.Add(Expression.Assign(expression3, ExpressionCache.Constant(true))); this._trapNestingCount++; } else { expression2 = null; expression = null; expression3 = null; if (this._trapNestingCount > 0) { exprs = new List<Expression>(); exprs.Add(Expression.Call(_functionContext, CachedReflectionInfo.FunctionContext_PushTrapHandlers, ExpressionCache.NullTypeArray, ExpressionCache.NullDelegateArray, ExpressionCache.NullTypeArray)); expression3 = this.NewTemp(typeof(bool), "trapHandlersPushed"); exprs.Add(Expression.Assign(expression3, ExpressionCache.Constant(true))); } } this._stmtCount += statements.Count; if (statements.Count == 1) { List<Expression> exprList = new List<Expression>(3); this.CompileTrappableExpression(exprList, statements[0]); exprList.Add(ExpressionCache.Empty); TryExpression item = Expression.TryCatch(Expression.Block(exprList), _stmtCatchHandlers); exprs.Add(item); } else { SwitchCase[] cases = new SwitchCase[statements.Count + 1]; LabelTarget[] targetArray = new LabelTarget[statements.Count + 1]; for (int i = 0; i <= statements.Count; i++) { targetArray[i] = Expression.Label(); cases[i] = Expression.SwitchCase(Expression.Goto(targetArray[i]), new Expression[] { ExpressionCache.Constant(i) }); } ParameterExpression expression5 = Expression.Variable(typeof(int), "stmt"); temps.Add(expression5); exprs.Add(Expression.Assign(expression5, ExpressionCache.Constant(0))); LabelTarget target = Expression.Label(); exprs.Add(Expression.Label(target)); List<Expression> list6 = new List<Expression> { Expression.Switch(expression5, cases) }; for (int j = 0; j < statements.Count; j++) { list6.Add(Expression.Label(targetArray[j])); list6.Add(Expression.Assign(expression5, ExpressionCache.Constant((int) (j + 1)))); this.CompileTrappableExpression(list6, statements[j]); } list6.Add(ExpressionCache.Empty); ParameterExpression expression6 = Expression.Variable(typeof(Exception), "exception"); MethodCallExpression expression7 = Expression.Call(CachedReflectionInfo.ExceptionHandlingOps_CheckActionPreference, _functionContext, expression6); CatchBlock block = Expression.Catch(expression6, Expression.Block(expression7, Expression.Goto(target))); TryExpression expression8 = Expression.TryCatch(Expression.Block(list6), new CatchBlock[] { _catchFlowControl, block }); exprs.Add(expression8); exprs.Add(Expression.Label(targetArray[statements.Count])); } if (this._trapNestingCount > 0) { List<ParameterExpression> variables = new List<ParameterExpression>(); List<Expression> expressions = new List<Expression>(); if (expression2 != null) { variables.Add(expression2); expressions.Add(Expression.Assign(expression, expression2)); } variables.Add(expression3); expressions.Add(Expression.IfThen(expression3, Expression.Call(_functionContext, CachedReflectionInfo.FunctionContext_PopTrapHandlers))); list.Add(Expression.Block(variables, new Expression[] { Expression.TryFinally(Expression.Block(exprs), Expression.Block(expressions)) })); } if (traps != null) { this._trapNestingCount--; } } }
public virtual void Write (SwitchCase @case) { VisitSwitchCase (@case); }
/// <summary> /// Gets the debug view for the specified switch case. /// </summary> /// <param name="switchCase">The switch case to get a debug view for.</param> /// <returns>Debug view for the specified switch case.</returns> public XNode GetDebugView(SwitchCase switchCase) { return(Visit(switchCase)); }
protected override SwitchCase VisitSwitchCase(SwitchCase node) { _nodes.Push(new XElement(nameof(SwitchCase), new XElement(nameof(node.Body), Visit(node.Body)), Visit(nameof(node.TestValues), node.TestValues))); return(node); }
public SwitchCaseProxy(SwitchCase node) { ContractUtils.RequiresNotNull(node, nameof(node)); _node = node; }
private static SwitchCase VisitSwitchCase(SwitchCase node) { throw new NotImplementedException(); }
private Variable VisitSwitchCase(SwitchCase node) { throw new NotSupportedException(); //this.Out("case "); //this.VisitExpressions<Expression>('(', node.TestValues, ')'); //this.Out(": ..."); }