Ejemplo n.º 1
0
 public UnresolvedIdentifier(string name, Scope scope, Identifier identifier, CatchScope catchScope)
 {
     Name = name;
     Scope = scope;
     Identifier = identifier;
     CatchScope = catchScope;
 }
Ejemplo n.º 2
0
 public CatchScope(ResolvedIdentifier identifier, Scope scope, CatchScope parent)
 {
     Identifier = identifier;
     Scope = scope;
     Parent = parent;
 }
Ejemplo n.º 3
0
            public void EnterCatch(string name)
            {
                var identifier = new ResolvedIdentifier(
                    name,
                    null,
                    IdentifierType.Local,
                    true
                );

                _resolvedIdentifiers.Add(identifier);

                _catchScope = new CatchScope(identifier, this, FindCatchScope());
            }
Ejemplo n.º 4
0
            public CatchClause ExitCatch(SyntaxNode statement)
            {
                var identifier = _catchScope.Identifier;

                _catchScope = _catchScope.Parent;

                return new CatchClause(identifier, statement);
            }
Ejemplo n.º 5
0
        //---------------------------------------------------------------------------------------
        // ParseTryStatement
        //
        //  TryStatement :
        //    'try' Block Catch Finally
        //
        //  Catch :
        //    <empty> | 'catch' '(' Identifier ')' Block
        //
        //  Finally :
        //    <empty> |
        //    'finally' Block
        //---------------------------------------------------------------------------------------
        private AstNode ParseTryStatement()
        {
            Context tryCtx = m_currentToken.Clone();
            Context tryEndContext = null;
            Block body = null;
            Context idContext = null;
            Block handler = null;
            CatchScope catchScope = null;
            Block finally_block = null;
            RecoveryTokenException excInFinally = null;
            m_blockType.Add(BlockType.Block);
            try
            {
                bool catchOrFinally = false;
                GetNextToken();
                if (JSToken.LeftCurly != m_currentToken.Token)
                {
                    ReportError(JSError.NoLeftCurly);
                }
                m_noSkipTokenSet.Add(NoSkipTokenSet.s_NoTrySkipTokenSet);
                try
                {
                    body = ParseBlock(out tryEndContext);
                }
                catch (RecoveryTokenException exc)
                {
                    if (IndexOfToken(NoSkipTokenSet.s_NoTrySkipTokenSet, exc) == -1)
                    {
                        // do nothing and just return the containing block, if any
                        throw;
                    }
                    else
                    {
                        body = exc._partiallyComputedNode as Block;
                        if (body == null)
                        {
                            body = new Block(exc._partiallyComputedNode.Context, this);
                            body.Append(exc._partiallyComputedNode);
                        }
                    }
                }
                finally
                {
                    m_noSkipTokenSet.Remove(NoSkipTokenSet.s_NoTrySkipTokenSet);
                }
                if (JSToken.Catch == m_currentToken.Token)
                {
                    m_noSkipTokenSet.Add(NoSkipTokenSet.s_NoTrySkipTokenSet);
                    try
                    {
                        catchOrFinally = true;
                        GetNextToken();
                        if (JSToken.LeftParenthesis != m_currentToken.Token)
                        {
                            ReportError(JSError.NoLeftParenthesis);
                        }

                        GetNextToken();
                        if (JSToken.Identifier != m_currentToken.Token)
                        {
                            string identifier = JSKeyword.CanBeIdentifier(m_currentToken.Token);
                            if (null != identifier)
                            {
                                idContext = m_currentToken.Clone();
                            }
                            else
                            {
                                ReportError(JSError.NoIdentifier);
                            }
                        }
                        else
                        {
                            idContext = m_currentToken.Clone();
                        }

                        GetNextToken();
                        m_noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet);
                        try
                        {
                            if (JSToken.RightParenthesis != m_currentToken.Token)
                            {
                                ReportError(JSError.NoRightParenthesis);
                            }
                            GetNextToken();
                        }
                        catch (RecoveryTokenException exc)
                        {
                            if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1)
                            {
                                exc._partiallyComputedNode = null;
                                // rethrow
                                throw;
                            }
                            else
                            {
                                if (m_currentToken.Token == JSToken.RightParenthesis)
                                {
                                    GetNextToken();
                                }
                            }
                        }
                        finally
                        {
                            m_noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet);
                        }

                        if (JSToken.LeftCurly != m_currentToken.Token)
                        {
                            ReportError(JSError.NoLeftCurly);
                        }

                        // create the catch-scope and push it onto the stack
                        catchScope = new CatchScope(ScopeStack.Peek(), idContext, this);
                        ScopeStack.Push(catchScope);

                        try
                        {
                            // parse the block
                            handler = ParseBlock();
                        }
                        finally
                        {
                            // pop off the catch scope and assign it to the block
                            ScopeStack.Pop();
                        }

                        tryCtx.UpdateWith(handler.Context);
                    }
                    catch (RecoveryTokenException exc)
                    {
                        if (exc._partiallyComputedNode == null)
                        {
                            handler = new Block(CurrentPositionContext(), this);
                        }
                        else
                        {
                            handler = exc._partiallyComputedNode as Block;
                            if (handler == null)
                            {
                                handler = new Block(exc._partiallyComputedNode.Context, this);
                                handler.Append(exc._partiallyComputedNode);
                            }
                        }
                        handler.BlockScope = catchScope;
                        if (IndexOfToken(NoSkipTokenSet.s_NoTrySkipTokenSet, exc) == -1)
                        {
                            throw;
                        }
                    }
                    finally
                    {
                        m_noSkipTokenSet.Remove(NoSkipTokenSet.s_NoTrySkipTokenSet);
                    }
                }

                try
                {
                    if (JSToken.Finally == m_currentToken.Token)
                    {
                        GetNextToken();
                        m_blockType.Add(BlockType.Finally);
                        try
                        {
                            finally_block = ParseBlock();
                            catchOrFinally = true;
                        }
                        finally
                        {
                            m_blockType.RemoveAt(m_blockType.Count - 1);
                        }
                        tryCtx.UpdateWith(finally_block.Context);
                    }
                }
                catch (RecoveryTokenException exc)
                {
                    excInFinally = exc; // thrown later so we can execute code below
                }

                if (!catchOrFinally)
                {
                    ReportError(JSError.NoCatch, true);
                    finally_block = new Block(CurrentPositionContext(), this); // make a dummy empty block
                }
            }
            finally
            {
                m_blockType.RemoveAt(m_blockType.Count - 1);
                if (handler != null)
                {
                    handler.BlockScope = catchScope;
                }
            }

            string catchVariableName = idContext == null ? null : idContext.Code;
            if (excInFinally != null)
            {
                excInFinally._partiallyComputedNode = new TryNode(tryCtx, this, body, catchVariableName, idContext, handler, finally_block);
                throw excInFinally;
            }
            return new TryNode(tryCtx, this, body, catchVariableName, idContext, handler, finally_block);
        }