Esempio n. 1
0
        /// <summary>
        /// Gets all matching handle blocks for the given record type.
        /// </summary>
        /// <param name="recordTypeName">The name of the record type that should be handled.</param>
        /// <returns>A list of matching handle blocks.</returns>
        private IEnumerable <IHandleBlockData> GetHandleBlocks(IRecord eventRecord, string recordTypeName)
        {
            // check whether it is an exception
            bool isException = eventRecord.RecordType.IsType(ExceptionRecord.RECORD_TYPE_NAME);

            List <IHandleBlockData> listOfHandleBlocks = new List <IHandleBlockData>();

            foreach (IScope scope in Memory.Scopes)
            {
                INestedScope nestedScope = scope as INestedScope;

                // check whether the scope is a block-scope that not is terminated

                if (nestedScope != null && nestedScope.IsTerminated == false)
                {
                    // check whether the scope is from an OBSERVE-block

                    IObserveScope observeScope = scope as IObserveScope;

                    if (observeScope != null)
                    {
                        // check whether the OBSERVE-block handles the thrown exception

                        var listOfMatchingHandleBlocks = from b in observeScope.HandleBlocks
                                                         where RecordHelper.IsDerivedType(Memory, recordTypeName, b.HandledRecordType.Name)
                                                         select b;

                        listOfHandleBlocks.AddRange(listOfMatchingHandleBlocks);
                    }


                    // The behavior for exceptions is different than the behavior for events:
                    // 1. An exception terminates all parent blocks until a HANDLE-block is found.
                    // 2. Only one matching HANDLE-block is required to stop the exception.

                    if (isException == true)
                    {
                        // mark the block as terminated
                        nestedScope.IsTerminated = true;

                        // if a HANDLE-block for the exception was found stop the search for other
                        // HANDLE-blocks because an exception only breaks the current OBSERVE-block.
                        if (listOfHandleBlocks.Count != 0)
                        {
                            return(listOfHandleBlocks);
                        }
                    }
                }
            }

            return(listOfHandleBlocks);
        }
Esempio n. 2
0
        /// <summary>
        /// Handles a .NET Exception that occurred during the interpretation of Synery code.
        /// </summary>
        /// <param name="exception">The thrown .NET Exception</param>
        /// <param name="context">The interpretation context that caused the Exception (e.g. used to print the line number).</param>
        /// <returns>
        /// false = Exception hasn't been handled, so please re-throw it.
        /// true = Exception handled. No further action is required. Continue interpretation.
        /// </returns>
        private bool HandleException(Exception exception, Antlr4.Runtime.ParserRuleContext context)
        {
            INestedScope nestedScope = Memory.Scopes.OfType <INestedScope>().FirstOrDefault();

            if (nestedScope != null && nestedScope.IsTerminated == true &&
                !(context is SyneryParser.ThrowStatementContext) &&
                !(exception is InterfaceBoosterException))
            {
                // The current block has already been terminated.
                // Therefore don't throw or create any new exceptions
                return(true);
            }
            else
            {
                if (context is SyneryParser.ObserveBlockContext)
                {
                    // We're now in an OBSERVE-block.
                    // Try to find a handle block that catches the exception.

                    ExecutionExceptionRecord executionException = new ExecutionExceptionRecord();
                    executionException.Message      = exception.Message;
                    executionException.Line         = context.Start.Line;
                    executionException.CharPosition = context.Start.Column;

                    this.HandleSyneryEvent(context, executionException.GetAsSyneryValue());

                    return(true);
                }
                if (exception is SyneryInterpretationException)
                {
                    // The exception already is an interpretation exception.
                    // Continue re-throwing it.
                    return(false);
                }

                /*
                 * It seems that the exception is not an interpretation exception.
                 * Create a new exception and enrich it with the parser-context and  a
                 * new message that contains all messages from the nested exceptions.
                 */

                string message = string.Format("An unexpected error occurred while interpreting '{1}' on line {2}: {0}{3}",
                                               Environment.NewLine,
                                               context.GetText(),
                                               context.Start.Line,
                                               ExceptionHelper.GetNestedExceptionMessages(exception));

                throw new SyneryInterpretationException(context, message, exception);
            }
        }
        public void Run(SyneryParser.ReturnStatementContext context)
        {
            IValue returnValue = null;

            // check for a correct scope

            if (!(Memory.CurrentScope is INestedScope))
            {
                string message = String.Format(
                    "Return statement is expected to be inside of a block scope. CurrentScope is of type '{0}'",
                    Memory.CurrentScope.GetType().Name);
                throw new SyneryInterpretationException(context, message);
            }

            if (context.expression() != null)
            {
                // evaluate expression for getting the value to return

                returnValue = Controller.Interpret <SyneryParser.ExpressionContext, IValue>(context.expression());
            }

            // broadcast the termination up to the function block

            IScope scope = Memory.CurrentScope;

            while (scope is INestedScope)
            {
                INestedScope nestedScope = (INestedScope)scope;

                nestedScope.IsTerminated = true;

                if (scope is IFunctionScope)
                {
                    // if its the scope of the function block break the loop and set the return value
                    ((IFunctionScope)scope).ReturnValue = returnValue;

                    break;
                }

                // get next scope from the scope tree
                scope = nestedScope.Parent;
            }
        }