示例#1
0
        public object VisitTryStatement(TryStatementAst tryStatementAst)
        {
            Block block = this._currentBlock;

            this._currentBlock = new Block();
            block.FlowsTo(this._currentBlock);
            tryStatementAst.Body.Accept(this);
            Block block2 = new Block();

            foreach (CatchClauseAst ast in tryStatementAst.CatchClauses)
            {
                this._currentBlock = new Block();
                block.FlowsTo(this._currentBlock);
                ast.Accept(this);
            }
            this._currentBlock = block2;
            block.FlowsTo(this._currentBlock);
            if (tryStatementAst.Finally != null)
            {
                tryStatementAst.Finally.Accept(this);
                Block next = new Block();
                this._currentBlock.FlowsTo(next);
                this._currentBlock = next;
            }
            return(null);
        }
示例#2
0
 private void CheckForFlowOutOfFinally(Ast ast, string label)
 {
     for (Ast ast2 = ast.Parent; ast2 != null; ast2 = ast2.Parent)
     {
         if ((ast2 is ScriptBlockAst) || (ast2 is TrapStatementAst))
         {
             break;
         }
         if (ast2 is NamedBlockAst)
         {
             return;
         }
         if (((label != null) && (ast2 is LoopStatementAst)) && LoopFlowException.MatchLoopLabel(label, ((LoopStatementAst)ast2).Label ?? ""))
         {
             return;
         }
         StatementBlockAst ast3 = ast2 as StatementBlockAst;
         if (ast3 != null)
         {
             TryStatementAst parent = ast3.Parent as TryStatementAst;
             if ((parent != null) && (parent.Finally == ast3))
             {
                 this._parser.ReportError(ast.Extent, ParserStrings.ControlLeavingFinally, new object[0]);
                 return;
             }
         }
     }
 }
示例#3
0
    public System.Object VisitTryStatement(System.Management.Automation.Language.TryStatementAst tryStatementAst)
    {
        IScriptExtent mappedExtent = MapExtent(tryStatementAst.Extent);

        StatementBlockAst           mappedBody         = (StatementBlockAst)VisitStatementBlock(tryStatementAst.Body);
        LinkedList <CatchClauseAst> mappedCatchClauses = new LinkedList <CatchClauseAst>();

        foreach (CatchClauseAst cc in tryStatementAst.CatchClauses)
        {
            mappedCatchClauses.AddLast((CatchClauseAst)VisitCatchClause(cc));
        }
        StatementBlockAst mappedFinally = tryStatementAst.Finally != null ? (StatementBlockAst)VisitStatementBlock(tryStatementAst.Finally) : null;

        return(new TryStatementAst(mappedExtent, mappedBody, mappedCatchClauses, mappedFinally));
    }
示例#4
0
 public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
 {
     if (tryStatementAst.CatchClauses.Count > 1)
     {
         for (int i = 0; i < (tryStatementAst.CatchClauses.Count - 1); i++)
         {
             CatchClauseAst ast = tryStatementAst.CatchClauses[i];
             for (int j = i + 1; j < tryStatementAst.CatchClauses.Count; j++)
             {
                 CatchClauseAst ast2 = tryStatementAst.CatchClauses[j];
                 if (ast.IsCatchAll)
                 {
                     this._parser.ReportError(Parser.Before(ast2.Extent), ParserStrings.EmptyCatchNotLast, new object[0]);
                     break;
                 }
                 if (!ast2.IsCatchAll)
                 {
                     foreach (TypeConstraintAst ast3 in ast.CatchTypes)
                     {
                         Type reflectionType = ast3.TypeName.GetReflectionType();
                         if (reflectionType != null)
                         {
                             foreach (TypeConstraintAst ast4 in ast2.CatchTypes)
                             {
                                 Type type2 = ast4.TypeName.GetReflectionType();
                                 if ((type2 != null) && ((reflectionType == type2) || type2.IsSubclassOf(reflectionType)))
                                 {
                                     this._parser.ReportError(ast4.Extent, ParserStrings.ExceptionTypeAlreadyCaught, new object[] { type2.FullName });
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return(AstVisitAction.Continue);
 }
示例#5
0
 public object VisitTryStatement(TryStatementAst tryStatementAst)
 {
     throw PSTraceSource.NewArgumentException("ast");
 }
示例#6
0
 public override AstVisitAction VisitTryStatement(TryStatementAst ast)
 {
     return(Check(ast));
 }
示例#7
0
 public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
 {
     throw new NotImplementedException(); //VisitTryStatement(tryStatementAst);
 }
 /// <summary/>
 public virtual object VisitTryStatement(TryStatementAst tryStatementAst)
 {
     return _decorated.VisitTryStatement(tryStatementAst);
 }
 public object VisitTryStatement(TryStatementAst tryStatementAst) { throw new UnexpectedElementException(); }
示例#10
0
        public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
        {
            if (tryStatementAst.CatchClauses.Count <= 1) return AstVisitAction.Continue;

            for (int i = 0; i < tryStatementAst.CatchClauses.Count - 1; ++i)
            {
                CatchClauseAst block1 = tryStatementAst.CatchClauses[i];
                for (int j = i + 1; j < tryStatementAst.CatchClauses.Count; ++j)
                {
                    CatchClauseAst block2 = tryStatementAst.CatchClauses[j];

                    if (block1.IsCatchAll)
                    {
                        _parser.ReportError(Parser.Before(block2.Extent), () => ParserStrings.EmptyCatchNotLast);
                        break;
                    }

                    if (block2.IsCatchAll) continue;

                    foreach (TypeConstraintAst typeLiteral1 in block1.CatchTypes)
                    {
                        Type type1 = typeLiteral1.TypeName.GetReflectionType();
                        // If the type can't be resolved yet, there isn't much we can do, so skip it.
                        if (type1 == null)
                            continue;

                        foreach (TypeConstraintAst typeLiteral2 in block2.CatchTypes)
                        {
                            Type type2 = typeLiteral2.TypeName.GetReflectionType();
                            // If the type can't be resolved yet, there isn't much we can do, so skip it.
                            if (type2 == null)
                                continue;

                            if (type1 == type2 || type2.IsSubclassOf(type1))
                            {
                                _parser.ReportError(typeLiteral2.Extent, () => ParserStrings.ExceptionTypeAlreadyCaught, type2.FullName);
                            }
                        }
                    }
                }
            }

            return AstVisitAction.Continue;
        }
示例#11
0
 /// <summary/>
 public virtual AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst) => DefaultVisit(tryStatementAst);
示例#12
0
文件: Compiler.cs 项目: nickchal/pash
 public object VisitTryStatement(TryStatementAst tryStatementAst)
 {
     List<ParameterExpression> temps = new List<ParameterExpression>();
     List<Expression> exprs = new List<Expression>();
     List<Expression> expressions = new List<Expression>();
     ParameterExpression item = this.NewTemp(typeof(bool), "oldActiveHandler");
     temps.Add(item);
     MemberExpression right = Expression.Property(_executionContextParameter, CachedReflectionInfo.ExecutionContext_ExceptionHandlerInEnclosingStatementBlock);
     exprs.Add(Expression.Assign(item, right));
     exprs.Add(Expression.Assign(right, ExpressionCache.Constant(true)));
     expressions.Add(Expression.Assign(right, item));
     this.CompileStatementListWithTraps(tryStatementAst.Body.Statements, tryStatementAst.Body.Traps, exprs, temps);
     List<CatchBlock> source = new List<CatchBlock>();
     if ((tryStatementAst.CatchClauses.Count == 1) && tryStatementAst.CatchClauses[0].IsCatchAll)
     {
         AutomaticVarSaver saver = new AutomaticVarSaver(this, SpecialVariables.UnderbarVarPath, 0);
         ParameterExpression expression = this.NewTemp(typeof(RuntimeException), "rte");
         ParameterExpression left = this.NewTemp(typeof(RuntimeException), "oldrte");
         NewExpression newValue = Expression.New(CachedReflectionInfo.ErrorRecord__ctor, new Expression[] { Expression.Property(expression, CachedReflectionInfo.RuntimeException_ErrorRecord), expression });
         List<Expression> list5 = new List<Expression> {
             Expression.Assign(left, _currentExceptionBeingHandled),
             Expression.Assign(_currentExceptionBeingHandled, expression),
             saver.SaveAutomaticVar(),
             saver.SetNewValue(newValue)
         };
         StatementBlockAst body = tryStatementAst.CatchClauses[0].Body;
         this.CompileStatementListWithTraps(body.Statements, body.Traps, list5, temps);
         TryExpression expression6 = Expression.TryFinally(Expression.Block(typeof(void), list5), Expression.Block(typeof(void), new Expression[] { saver.RestoreAutomaticVar(), Expression.Assign(_currentExceptionBeingHandled, left) }));
         source.Add(Expression.Catch(typeof(PipelineStoppedException), Expression.Rethrow()));
         source.Add(Expression.Catch(expression, Expression.Block(saver.GetTemps().Append<ParameterExpression>(left).ToArray<ParameterExpression>(), new Expression[] { expression6 })));
     }
     else if (tryStatementAst.CatchClauses.Any<CatchClauseAst>())
     {
         int num = 0;
         foreach (CatchClauseAst ast2 in tryStatementAst.CatchClauses)
         {
             num += Math.Max(ast2.CatchTypes.Count, 1);
         }
         Type[] typeArray = new Type[num];
         Expression array = Expression.Constant(typeArray);
         List<Expression> list7 = new List<Expression>();
         List<SwitchCase> list8 = new List<SwitchCase>();
         int i = 0;
         int index = 0;
         ParameterExpression expression8 = Expression.Parameter(typeof(RuntimeException));
         foreach (CatchClauseAst ast3 in tryStatementAst.CatchClauses)
         {
             if (ast3.IsCatchAll)
             {
                 typeArray[index] = typeof(ExceptionHandlingOps.CatchAll);
             }
             else
             {
                 foreach (TypeConstraintAst ast4 in ast3.CatchTypes)
                 {
                     typeArray[index] = ast4.TypeName.GetReflectionType();
                     if (typeArray[index] == null)
                     {
                         IndexExpression expression9 = Expression.ArrayAccess(array, new Expression[] { ExpressionCache.Constant(index) });
                         list7.Add(Expression.IfThen(Expression.Equal(expression9, ExpressionCache.NullType), Expression.Assign(expression9, Expression.Call(CachedReflectionInfo.TypeOps_ResolveTypeName, Expression.Constant(ast4.TypeName)))));
                     }
                     index++;
                 }
             }
             BlockExpression expression10 = Expression.Block(typeof(void), new Expression[] { this.Compile(ast3.Body) });
             if (ast3.IsCatchAll)
             {
                 list8.Add(Expression.SwitchCase(expression10, new Expression[] { ExpressionCache.Constant(i) }));
                 i++;
             }
             else
             {
                 list8.Add(Expression.SwitchCase(expression10, Enumerable.Range(i, i + ast3.CatchTypes.Count).Select<int, Expression>(new Func<int, Expression>(ExpressionCache.Constant))));
                 i += ast3.CatchTypes.Count;
             }
         }
         if (list7.Any<Expression>())
         {
             array = Expression.Block(list7.Append<Expression>(array));
         }
         AutomaticVarSaver saver2 = new AutomaticVarSaver(this, SpecialVariables.UnderbarVarPath, 0);
         MethodCallExpression switchValue = Expression.Call(CachedReflectionInfo.ExceptionHandlingOps_FindMatchingHandler, this.LocalVariablesParameter, expression8, array, _executionContextParameter);
         ParameterExpression expression12 = this.NewTemp(typeof(RuntimeException), "oldrte");
         TryExpression expression13 = Expression.TryFinally(Expression.Block(typeof(void), new Expression[] { Expression.Assign(expression12, _currentExceptionBeingHandled), Expression.Assign(_currentExceptionBeingHandled, expression8), saver2.SaveAutomaticVar(), Expression.Switch(switchValue, Expression.Call(CachedReflectionInfo.ExceptionHandlingOps_CheckActionPreference, _functionContext, expression8), list8.ToArray()) }), Expression.Block(saver2.RestoreAutomaticVar(), Expression.Assign(_currentExceptionBeingHandled, expression12)));
         source.Add(Expression.Catch(typeof(PipelineStoppedException), Expression.Rethrow()));
         source.Add(Expression.Catch(expression8, Expression.Block(saver2.GetTemps().Append<ParameterExpression>(expression12).ToArray<ParameterExpression>(), new Expression[] { expression13 })));
     }
     if (tryStatementAst.Finally != null)
     {
         ParameterExpression expression14 = this.NewTemp(typeof(bool), "oldIsStopping");
         temps.Add(expression14);
         expressions.Add(Expression.Assign(expression14, Expression.Call(CachedReflectionInfo.ExceptionHandlingOps_SuspendStoppingPipeline, _executionContextParameter)));
         List<Expression> list9 = new List<Expression>();
         this.CompileStatementListWithTraps(tryStatementAst.Finally.Statements, tryStatementAst.Finally.Traps, list9, temps);
         if (!list9.Any<Expression>())
         {
             list9.Add(ExpressionCache.Empty);
         }
         expressions.Add(Expression.Block(new Expression[] { Expression.TryFinally(Expression.Block(list9), Expression.Call(CachedReflectionInfo.ExceptionHandlingOps_RestoreStoppingPipeline, _executionContextParameter, expression14)) }));
     }
     if (!exprs.Last<Expression>().Type.Equals(typeof(void)))
     {
         exprs.Add(ExpressionCache.Empty);
     }
     if (source.Any<CatchBlock>())
     {
         return Expression.Block(temps.ToArray(), new Expression[] { Expression.TryCatchFinally(Expression.Block(exprs), Expression.Block(expressions), source.ToArray()) });
     }
     return Expression.Block(temps.ToArray(), new Expression[] { Expression.TryFinally(Expression.Block(exprs), Expression.Block(expressions)) });
 }
示例#13
0
 public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
 {
     if (tryStatementAst.CatchClauses.Count > 1)
     {
         for (int i = 0; i < (tryStatementAst.CatchClauses.Count - 1); i++)
         {
             CatchClauseAst ast = tryStatementAst.CatchClauses[i];
             for (int j = i + 1; j < tryStatementAst.CatchClauses.Count; j++)
             {
                 CatchClauseAst ast2 = tryStatementAst.CatchClauses[j];
                 if (ast.IsCatchAll)
                 {
                     this._parser.ReportError(Parser.Before(ast2.Extent), ParserStrings.EmptyCatchNotLast, new object[0]);
                     break;
                 }
                 if (!ast2.IsCatchAll)
                 {
                     foreach (TypeConstraintAst ast3 in ast.CatchTypes)
                     {
                         Type reflectionType = ast3.TypeName.GetReflectionType();
                         if (reflectionType != null)
                         {
                             foreach (TypeConstraintAst ast4 in ast2.CatchTypes)
                             {
                                 Type type2 = ast4.TypeName.GetReflectionType();
                                 if ((type2 != null) && ((reflectionType == type2) || type2.IsSubclassOf(reflectionType)))
                                 {
                                     this._parser.ReportError(ast4.Extent, ParserStrings.ExceptionTypeAlreadyCaught, new object[] { type2.FullName });
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return AstVisitAction.Continue;
 }
示例#14
0
 /// <summary/>
 public virtual object VisitTryStatement(TryStatementAst tryStatementAst) { return null; }
示例#15
0
 public object VisitTryStatement(TryStatementAst tryStatementAst)
 {
     return(false);
 }
示例#16
0
 public override AstVisitAction VisitTryStatement(TryStatementAst ast) { return CheckParent(ast); }
 public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
 {
     this.ReportError(tryStatementAst, () => ParserStrings.TryStatementNotSupportedInDataSection, new object[0]);
     return(AstVisitAction.Continue);
 }
示例#18
0
        public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
        {
            try
            {
                tryStatementAst.Body.Visit(this);
            }
            catch (FlowControlException)
            {
                // flow control (return, exit, continue, break) is nothing the user should see and is propagated
                throw;
            }
            catch (Exception ex)
            {
                SetUnderscoreVariable(ex);

                tryStatementAst.CatchClauses.Last().Body.Visit(this);
            }

            return AstVisitAction.SkipChildren;
        }
示例#19
0
 public override AstVisitAction VisitTryStatement(TryStatementAst ast)
 {
     return this.Check(ast);
 }
示例#20
0
        public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
        {
            try
            {
                tryStatementAst.Body.Visit(this);
            }
            catch (ReturnException)
            {
                throw;
            }
            catch (Exception ex)
            {
                SetUnderscoreVariable(ex);

                tryStatementAst.CatchClauses.Last().Body.Visit(this);
            }

            return AstVisitAction.SkipChildren;
        }
示例#21
0
        public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
        {
            try
            {
                tryStatementAst.Body.Visit(this);
            }
            catch (FlowControlException)
            {
                // flow control (return, exit, continue, break) is nothing the user should see and is propagated
                throw;
            }
            catch (Exception ex)
            {
                SetUnderscoreVariable(ex);

                // not yet considered: no catches, special catches!
                tryStatementAst.CatchClauses.Last().Body.Visit(this);
            }
            finally
            {
                if (tryStatementAst.Finally != null)
                {
                    tryStatementAst.Finally.Visit(this);
                }
            }

            return AstVisitAction.SkipChildren;
        }
示例#22
0
 public virtual AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
 {
     return AstVisitAction.Continue;
 }
示例#23
0
 public object VisitTryStatement(TryStatementAst tryStatementAst) { return AutomationNull.Value; }
示例#24
0
 public object VisitTryStatement(TryStatementAst tryStatementAst) { throw PSTraceSource.NewArgumentException("ast"); }
示例#25
0
        public object VisitTryStatement(TryStatementAst tryStatementAst)
        {
            var temps = new List<ParameterExpression>();
            var tryBlockExprs = new List<Expression>();
            var finallyBlockExprs = new List<Expression>();

            // We must set $ExecutionContext.PropagateExceptionsToEnclosingStatementBlock = $true so we don't prompt
            // if an exception is raised, and we must restore the previous value when leaving because we can't
            // know if we're dynamically executing code guarded by a try/catch.
            var oldActiveHandler = NewTemp(typeof(bool), "oldActiveHandler");
            temps.Add(oldActiveHandler);
            var handlerInScope = Expression.Property(_executionContextParameter,
                                     CachedReflectionInfo.ExecutionContext_ExceptionHandlerInEnclosingStatementBlock);
            tryBlockExprs.Add(Expression.Assign(oldActiveHandler, handlerInScope));
            tryBlockExprs.Add(Expression.Assign(handlerInScope, ExpressionCache.Constant(true)));
            finallyBlockExprs.Add(Expression.Assign(handlerInScope, oldActiveHandler));

            CompileStatementListWithTraps(tryStatementAst.Body.Statements, tryStatementAst.Body.Traps, tryBlockExprs, temps);

            var catches = new List<CatchBlock>();

            if (tryStatementAst.CatchClauses.Count == 1 && tryStatementAst.CatchClauses[0].IsCatchAll)
            {
                // Generate:
                //    catch (RuntimeException rte)
                //    {
                //        oldrte = context.CurrentExceptionBeingHandled
                //        context.CurrentExceptionBeingHandled = rte
                //        oldDollarUnder = $_
                //        $_ = new ErrorRecord(rte.ErrorRecord, rte)
                //        try {
                //            user catch code
                //        } finally {
                //            $_ = oldDollarUnder
                //            context.CurrentExceptionBeingHandled = oldrte
                //        }
                AutomaticVarSaver avs = new AutomaticVarSaver(this, SpecialVariables.UnderbarVarPath,
                                                              (int)AutomaticVariable.Underbar);
                var rte = NewTemp(typeof(RuntimeException), "rte");
                var oldrte = NewTemp(typeof(RuntimeException), "oldrte");
                var errorRecord = Expression.New(CachedReflectionInfo.ErrorRecord__ctor,
                                                 Expression.Property(rte, CachedReflectionInfo.RuntimeException_ErrorRecord),
                                                 rte);
                var catchExprs = new List<Expression>
                                     {
                                     Expression.Assign(oldrte, s_currentExceptionBeingHandled),
                                     Expression.Assign(s_currentExceptionBeingHandled, rte),
                                     avs.SaveAutomaticVar(),
                                     avs.SetNewValue(errorRecord)
                                 };
                StatementBlockAst statementBlock = tryStatementAst.CatchClauses[0].Body;
                CompileStatementListWithTraps(statementBlock.Statements, statementBlock.Traps, catchExprs, temps);

                var tf = Expression.TryFinally(
                    Expression.Block(typeof(void), catchExprs),
                    Expression.Block(typeof(void),
                                     avs.RestoreAutomaticVar(),
                                     Expression.Assign(s_currentExceptionBeingHandled, oldrte)));

                catches.Add(Expression.Catch(typeof(PipelineStoppedException), Expression.Rethrow()));
                catches.Add(Expression.Catch(rte, Expression.Block(avs.GetTemps().Append(oldrte).ToArray(), tf)));
            }
            else if (tryStatementAst.CatchClauses.Count > 0)
            {
                // We can't generate a try/catch in quite the way one might expect for a few reasons:
                //     * At compile time, we may not have loaded the types that are being caught
                //     * We wrap exceptions in a RuntimeException so they can carry a position.
                //
                // Instead, we generate something like:
                //     try {}
                //     catch (RuntimeException re) {
                //         try
                //         {
                //             oldexception = context.CurrentExceptionBeingHandled
                //             context.CurrentExceptionBeingHandled = re
                //             old_ = $_
                //             $_ = re.ErrorRecord
                //             switch (ExceptionHandlingOps.FindMatchingHandler(re, types))
                //             {
                //             case 0:
                //                  /* first handler */
                //                  break;
                //             case 1:
                //             case 2:
                //                  /* second handler (we do allow a single handler for multiple types) */
                //                  break;
                //             default:
                //                  /* no matching handler, but could be a trap or user might want prompting */
                //                  /* will rethrow the exception if that's what we need to do */
                //                  ExceptionHandlingOps.CheckActionPreference(functionContext, exception);
                //             }
                //         } finally {
                //             $_ = old_
                //             context.CurrentExceptionBeingHandled = oldexception
                //         }
                //     }

                // Try to get the types at compile time.  We could end up with nulls in this array, we'll handle
                // that with runtime code.
                int countTypes = 0;
                for (int index = 0; index < tryStatementAst.CatchClauses.Count; index++)
                {
                    var c = tryStatementAst.CatchClauses[index];
                    // If CatchTypes.Count is empty, we still want to count the catch all handler.
                    countTypes += Math.Max(c.CatchTypes.Count, 1);
                }

                var catchTypes = new Type[countTypes];
                Expression catchTypesExpr = Expression.Constant(catchTypes);
                var dynamicCatchTypes = new List<Expression>();
                var cases = new List<SwitchCase>();
                int handlerTypeIndex = 0;
                int i = 0;

                var exception = Expression.Parameter(typeof(RuntimeException));
                for (int index = 0; index < tryStatementAst.CatchClauses.Count; index++)
                {
                    var c = tryStatementAst.CatchClauses[index];
                    if (c.IsCatchAll)
                    {
                        catchTypes[i] = typeof(ExceptionHandlingOps.CatchAll);
                    }
                    else
                    {
                        for (int index1 = 0; index1 < c.CatchTypes.Count; index1++)
                        {
                            var ct = c.CatchTypes[index1];
                            catchTypes[i] = ct.TypeName.GetReflectionType();
                            if (catchTypes[i] == null)
                            {
                                // Type needs to be resolved at runtime, so we'll use code like:
                                //
                                // if (catchTypes[i] == null) catchTypes[i] = ResolveTypeName(ct.TypeName)
                                //
                                // We use a constant array, resolve just once (unless it fails) to prevent re-resolving
                                // each time it executes.

                                var indexExpr = Expression.ArrayAccess(catchTypesExpr, ExpressionCache.Constant(i));
                                dynamicCatchTypes.Add(
                                    Expression.IfThen(
                                        Expression.Equal(indexExpr, ExpressionCache.NullType),
                                        Expression.Assign(
                                            indexExpr,
                                            Expression.Call(CachedReflectionInfo.TypeOps_ResolveTypeName,
                                                            Expression.Constant(ct.TypeName),
                                                            Expression.Constant(ct.Extent)))));
                            }
                            i += 1;
                        }
                    }

                    // Wrap the body in a void block so all cases have the same type.
                    var catchBody = Expression.Block(typeof(void), Compile(c.Body));

                    if (c.IsCatchAll)
                    {
                        cases.Add(Expression.SwitchCase(catchBody,
                                                        ExpressionCache.Constant(handlerTypeIndex)));
                        handlerTypeIndex += 1;
                    }
                    else
                    {
                        cases.Add(Expression.SwitchCase(catchBody,
                                                        Enumerable.Range(handlerTypeIndex,
                                                                         handlerTypeIndex + c.CatchTypes.Count).Select(
                                                                             ExpressionCache.Constant)));
                        handlerTypeIndex += c.CatchTypes.Count;
                    }
                }

                if (dynamicCatchTypes.Count > 0)
                {
                    // This might be worth a strict-mode check - if there was a typo, the typo isn't discovered until
                    // the first time an exception is raised, which is rather unfortunate.

                    catchTypesExpr = Expression.Block(dynamicCatchTypes.Append(catchTypesExpr));
                }

                AutomaticVarSaver avs = new AutomaticVarSaver(this, SpecialVariables.UnderbarVarPath,
                                                              (int)AutomaticVariable.Underbar);
                var swCond = Expression.Call(CachedReflectionInfo.ExceptionHandlingOps_FindMatchingHandler,
                                             LocalVariablesParameter, exception, catchTypesExpr, _executionContextParameter);
                var oldexception = NewTemp(typeof(RuntimeException), "oldrte");

                var tf = Expression.TryFinally(
                    Expression.Block(
                        typeof(void),
                        Expression.Assign(oldexception, s_currentExceptionBeingHandled),
                        Expression.Assign(s_currentExceptionBeingHandled, exception),
                        avs.SaveAutomaticVar(),
                        // $_ is set in the call to ExceptionHandlingOps.FindMatchingHandler
                        Expression.Switch(
                            swCond,
                            Expression.Call(
                                CachedReflectionInfo.ExceptionHandlingOps_CheckActionPreference,
                                _functionContext, exception),
                            cases.ToArray())),
                    Expression.Block(
                        avs.RestoreAutomaticVar(),
                        Expression.Assign(s_currentExceptionBeingHandled, oldexception)));

                catches.Add(Expression.Catch(typeof(PipelineStoppedException), Expression.Rethrow()));
                catches.Add(Expression.Catch(exception, Expression.Block(avs.GetTemps().Append(oldexception).ToArray(), tf)));
            }

            if (tryStatementAst.Finally != null)
            {
                // Generate:
                //     oldIsStopping = ExceptionHandlingOps.SuspendStoppingPipeline(executionContext);
                //     try {
                //         user finally statements
                //     } finally {
                //         ExceptionHandlingOps.RestoreStoppingPipeline(executionContext, oldIsStopping);
                //     }

                var oldIsStopping = NewTemp(typeof(bool), "oldIsStopping");
                temps.Add(oldIsStopping);
                finallyBlockExprs.Add(
                    Expression.Assign(oldIsStopping,
                                      Expression.Call(CachedReflectionInfo.ExceptionHandlingOps_SuspendStoppingPipeline,
                                                      _executionContextParameter)));
                var nestedFinallyExprs = new List<Expression>();
                CompileStatementListWithTraps(tryStatementAst.Finally.Statements,
                                              tryStatementAst.Finally.Traps, nestedFinallyExprs, temps);
                if (nestedFinallyExprs.Count == 0)
                {
                    nestedFinallyExprs.Add(ExpressionCache.Empty);
                }

                finallyBlockExprs.Add(Expression.Block(
                    Expression.TryFinally(
                        Expression.Block(nestedFinallyExprs),
                        Expression.Call(CachedReflectionInfo.ExceptionHandlingOps_RestoreStoppingPipeline,
                                        _executionContextParameter,
                                        oldIsStopping))));
            }

            // Our result must have void type, so make sure it does.
            if (tryBlockExprs[tryBlockExprs.Count - 1].Type != typeof(void))
            {
                tryBlockExprs.Add(ExpressionCache.Empty);
            }

            if (catches.Count > 0)
            {
                return Expression.Block(
                    temps.ToArray(),
                    Expression.TryCatchFinally(
                        Expression.Block(tryBlockExprs),
                        Expression.Block(finallyBlockExprs),
                        catches.ToArray()));
            }

            return Expression.Block(
                temps.ToArray(),
                Expression.TryFinally(
                    Expression.Block(tryBlockExprs),
                    Expression.Block(finallyBlockExprs)));
        }
示例#26
0
 /// <summary/>
 public virtual object VisitTryStatement(TryStatementAst tryStatementAst)
 {
     return(null);
 }
示例#27
0
 public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
 {
     this.ReportError(tryStatementAst, () => ParserStrings.TryStatementNotSupportedInDataSection, new object[0]);
     return AstVisitAction.Continue;
 }
示例#28
0
 public object VisitTryStatement(TryStatementAst tryStatementAst)
 {
     return false;
 }
示例#29
0
 public object VisitTryStatement(TryStatementAst tryStatementAst)
 {
     Block block = this._currentBlock;
     this._currentBlock = new Block();
     block.FlowsTo(this._currentBlock);
     tryStatementAst.Body.Accept(this);
     Block block2 = new Block();
     foreach (CatchClauseAst ast in tryStatementAst.CatchClauses)
     {
         this._currentBlock = new Block();
         block.FlowsTo(this._currentBlock);
         ast.Accept(this);
     }
     this._currentBlock = block2;
     block.FlowsTo(this._currentBlock);
     if (tryStatementAst.Finally != null)
     {
         tryStatementAst.Finally.Accept(this);
         Block next = new Block();
         this._currentBlock.FlowsTo(next);
         this._currentBlock = next;
     }
     return null;
 }
示例#30
0
 /// <summary/>
 public virtual AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst)
 {
     return(AstVisitAction.Continue);
 }
        /// <summary>
        /// Visit try statement
        /// </summary>
        /// <param name="tryStatementAst"></param>
        /// <returns></returns>
        public object VisitTryStatement(TryStatementAst tryStatementAst)
        {
            if (tryStatementAst == null) return null;

            // We don't attempt to accurately model flow in a try catch because every statement
            // can flow to each catch.  Instead, we'll assume the try block is not executed (because the very first statement
            // may throw), and have the data flow assume the block before the try is all that can reach the catches and finally.

            var blockBeforeTry = _currentBlock;
            _currentBlock = new Block();
            blockBeforeTry.FlowsTo(_currentBlock);

            tryStatementAst.Body.Visit(this.Decorator);

            Block lastBlockInTry = _currentBlock;
            var finallyFirstBlock = tryStatementAst.Finally == null ? null : new Block();
            Block finallyLastBlock = null;

            // This is the first block after all the catches and finally (if present).
            var afterTry = new Block();

            bool isCatchAllPresent = false;

            foreach (var catchAst in tryStatementAst.CatchClauses)
            {
                if (catchAst.IsCatchAll)
                {
                    isCatchAllPresent = true;
                }

                // Any statement in the try block could throw and reach the catch, so assume the worst (from a data
                // flow perspective) and make the predecessor to the catch the block before entering the try.
                _currentBlock = new Block();
                blockBeforeTry.FlowsTo(_currentBlock);
                catchAst.Visit(this.Decorator);
                _currentBlock.FlowsTo(finallyFirstBlock ?? afterTry);
            }

            if (finallyFirstBlock != null)
            {
                lastBlockInTry.FlowsTo(finallyFirstBlock);

                _currentBlock = finallyFirstBlock;
                tryStatementAst.Finally.Visit(this.Decorator);
                _currentBlock.FlowsTo(afterTry);

                finallyLastBlock = _currentBlock;

                // For finally block, there are 2 cases: when try-body throw and when it doesn't.
                // For these two cases value of 'finallyLastBlock._throws' would be different.
                if (!isCatchAllPresent)
                {
                    // This flow exist only, if there is no catch for all exceptions.
                    blockBeforeTry.FlowsTo(finallyFirstBlock);

                    var rethrowAfterFinallyBlock = new Block();
                    finallyLastBlock.FlowsTo(rethrowAfterFinallyBlock);
                    rethrowAfterFinallyBlock._throws = true;
                    rethrowAfterFinallyBlock.FlowsTo(_exitBlock);
                }

                // This flow always exists.
                finallyLastBlock.FlowsTo(afterTry);
            }
            else
            {
                lastBlockInTry.FlowsTo(afterTry);
            }

            _currentBlock = afterTry;

            return null;
        }
示例#32
0
 public object VisitTryStatement(TryStatementAst tryStatementAst)
 {
     return(AutomationNull.Value);
 }
 public object VisitTryStatement(TryStatementAst tryStatementAst)
 {
     throw new NotImplementedException();
 }