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));
            }
Пример #2
0
 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();
 }
Пример #5
0
 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;
    }
Пример #8
0
        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;
        }
Пример #9
0
 /// <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)));
 }
Пример #10
0
        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;
            }
        }
Пример #11
0
 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);
		}
Пример #13
0
 /// <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));
 }
Пример #14
0
 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);
 }
Пример #15
0
 public SwitchCaseProxy(SwitchCase node)
 {
     ContractUtils.RequiresNotNull(node, nameof(node));
     _node = node;
 }
Пример #16
0
 public SwitchCaseProxy(SwitchCase node)
 {
     ContractUtils.RequiresNotNull(node, nameof(node));
     _node = node;
 }
Пример #17
0
 private static SwitchCase VisitSwitchCase(SwitchCase node)
 {
     throw new NotImplementedException();
 }
Пример #18
0
        private Variable VisitSwitchCase(SwitchCase node)
        {
            throw new NotSupportedException();

            //this.Out("case ");
            //this.VisitExpressions<Expression>('(', node.TestValues, ')');
            //this.Out(": ...");
        }