示例#1
0
        void RemoveNextLineUnindentBlocks()
        {
            while (block != null && block.PopOnNextLine)
                block = block.Parent;

            var curBlock = block;

            while (curBlock != null)
            {
                if (curBlock.Parent != null && curBlock.Parent.PopOnNextLine)
                    curBlock.Parent = curBlock.Parent.Parent;

                curBlock = curBlock.Parent;
            }
        }
示例#2
0
 CodeBlock PushBlock(CodeBlock previousBlock=null)
 {
     return block = new CodeBlock {
         previousBlock=previousBlock,
         LastPreBlockIdentifier=Lexer.LastToken ?? null,
         Parent=block,
         StartLocation = t.Location
     };
 }
示例#3
0
        public CodeBlock CalculateIndentation(TextReader code, int line)
        {
            block = null;

            Lexer = new Lexer(code);
            maxLine = line;

            Lexer.NextToken();
            DToken lastToken = null;

            while (!Lexer.IsEOF)
            {
                if (t != null && la.line > t.line && t.line < maxLine)
                {
                    RemoveNextLineUnindentBlocks();
                }

                lastToken = t;
                Lexer.NextToken();

                if (IsEOF)
                {
                    if (la.line > maxLine || Lexer.IsEOF)
                        lastLineIndent = null;

                    if (t.line>maxLine)
                        break;
                }

                /*
                 * if(..)
                 *		for(...)
                 *			while(...)
                 *				foo();
                 *	// No indentation anymore!
                 */
                if (t.Kind == DTokens.Comma || t.Kind == DTokens.Semicolon && maxLine>t.line && la.line > t.line)
                {
                    if (block == null)
                        continue;

                    if (block.Reason == CodeBlock.IndentReason.UnfinishedStatement)
                        PopBlock();

                    while (
                        block != null &&
                        block.Reason == CodeBlock.IndentReason.SingleLineStatement &&
                        !IsSemicolonContainingStatement)
                        PopBlock();
                }

                // (,[,{
                else if (t.Kind == DTokens.OpenParenthesis ||
                    t.Kind == DTokens.OpenSquareBracket ||
                    t.Kind == DTokens.OpenCurlyBrace)
                {
                    var tBlock = block;

                    if (block != null && (
                        block.Reason == CodeBlock.IndentReason.SingleLineStatement ||
                        block.Reason == CodeBlock.IndentReason.UnfinishedStatement))
                    {
                        PopBlock();
                    }

                    PushBlock(tBlock).BlockStartToken = t.Kind;
                }

                // ),],}
                else if (t.Kind == DTokens.CloseParenthesis ||
                    t.Kind == DTokens.CloseSquareBracket ||
                    t.Kind == DTokens.CloseCurlyBrace)
                {
                    if (t.Kind == DTokens.CloseCurlyBrace)
                    {
                        while (block != null && !block.IsClampBlock)
                            PopBlock();

                        /*
                         * If the last token was on this line OR if it's eof but on the following line,
                         * decrement indent on next line only.
                         */
                        if (lastToken!=null && lastToken.line == t.line && block != null)
                        {
                            block.PopOnNextLine = true;
                        }
                        else
                            PopBlock();
                    }
                    else
                    {
                        while (block != null && !block.IsClampBlock)
                            PopBlock();

                        if (lastLineIndent == null && (block == null || block.StartLocation.Line < t.line))
                            lastLineIndent = block;

                        if (t.Kind == DTokens.CloseParenthesis &&
                            block != null &&
                            block.BlockStartToken == DTokens.OpenParenthesis &&
                            la.Kind!=DTokens.OpenCurlyBrace)
                        {
                            block=block.previousBlock;

                            continue;
                        }
                        else
                            PopBlock();

                        if (t.Kind == DTokens.CloseParenthesis &&
                            block != null &&
                            block.BlockStartToken == DTokens.OpenParenthesis)
                        {
                            if (la.Kind == DTokens.OpenCurlyBrace && la.line > t.line)
                                PopBlock();
                            else if (block!=null && block.LastPreBlockIdentifier!=null && IsPreStatementToken(block.LastPreBlockIdentifier.Kind))
                                block = block.previousBlock;
                        }
                    }
                }

                else if ((DParser.IsAttributeSpecifier(t.Kind, la.Kind) && la.Kind==DTokens.Colon) || t.Kind == DTokens.Case || t.Kind==DTokens.Default)
                {
                    while (block != null && block.BlockStartToken!=DTokens.OpenCurlyBrace)
                        PopBlock();

                    PushBlock().Reason = CodeBlock.IndentReason.StatementLabel;

                    HadCaseStatementBegin = true;
                }
                else if (t.Kind == DTokens.Colon)
                {
                    if (HadCaseStatementBegin)
                    {
                        while (block != null && block.Reason != CodeBlock.IndentReason.StatementLabel)
                            PopBlock();
                        HadCaseStatementBegin = false;
                    }
                }

                // Don't indent these in front of function bodies
                else if (t.Kind == DTokens.In || t.Kind == DTokens.Out || t.Kind == DTokens.Body)
                {
                    if (block != null && block.Reason == CodeBlock.IndentReason.UnfinishedStatement)
                        PopBlock();
                }

                else if (block == null ||
                    block.Reason != CodeBlock.IndentReason.UnfinishedStatement &&
                    block.Reason != CodeBlock.IndentReason.SingleLineStatement)
                    PushBlock().Reason = CodeBlock.IndentReason.UnfinishedStatement;
            }

            if (t!=null && la.line > t.line)
                RemoveNextLineUnindentBlocks();

            return lastLineIndent ?? block;
        }
示例#4
0
 CodeBlock PopBlock()
 {
     if (block != null)
         return block = block.Parent;
     return null;
 }
示例#5
0
        public CodeBlock CalculateIndentation(TextReader code, int line)
        {
            block = null;

            Lexer   = new Lexer(code);
            maxLine = line;

            Lexer.NextToken();
            DToken lastToken = null;

            while (!Lexer.IsEOF)
            {
                if (t != null && la.Line > t.Line && t.Line < maxLine)
                {
                    RemoveNextLineUnindentBlocks();
                }

                lastToken = t;
                Lexer.NextToken();

                if (IsEOF)
                {
                    if (la.Line > maxLine || Lexer.IsEOF)
                    {
                        lastLineIndent = null;
                    }

                    if (t.Line > maxLine)
                    {
                        break;
                    }
                }

                /*
                 * if(..)
                 *		for(...)
                 *			while(...)
                 *				foo();
                 *	// No indentation anymore!
                 */
                if (t.Kind == DTokens.Comma || t.Kind == DTokens.Semicolon && maxLine > t.Line && la.Line > t.Line)
                {
                    if (block == null)
                    {
                        continue;
                    }

                    if (block.Reason == CodeBlock.IndentReason.UnfinishedStatement)
                    {
                        PopBlock();
                    }

                    while (
                        block != null &&
                        block.Reason == CodeBlock.IndentReason.SingleLineStatement &&
                        !IsSemicolonContainingStatement)
                    {
                        PopBlock();
                    }
                }

                // (,[,{
                else if (t.Kind == DTokens.OpenParenthesis ||
                         t.Kind == DTokens.OpenSquareBracket ||
                         t.Kind == DTokens.OpenCurlyBrace)
                {
                    var tBlock = block;

                    if (block != null && (
                            block.Reason == CodeBlock.IndentReason.SingleLineStatement ||
                            block.Reason == CodeBlock.IndentReason.UnfinishedStatement))
                    {
                        PopBlock();
                    }

                    PushBlock(tBlock).BlockStartToken = t.Kind;
                }

                // ),],}
                else if (t.Kind == DTokens.CloseParenthesis ||
                         t.Kind == DTokens.CloseSquareBracket ||
                         t.Kind == DTokens.CloseCurlyBrace)
                {
                    if (t.Kind == DTokens.CloseCurlyBrace)
                    {
                        while (block != null && !block.IsClampBlock)
                        {
                            PopBlock();
                        }

                        /*
                         * If the last token was on this line OR if it's eof but on the following line,
                         * decrement indent on next line only.
                         */
                        if (lastToken != null && lastToken.Line == t.Line && block != null)
                        {
                            block.PopOnNextLine = true;
                        }
                        else
                        {
                            PopBlock();
                        }
                    }
                    else
                    {
                        while (block != null && !block.IsClampBlock)
                        {
                            PopBlock();
                        }

                        if (lastLineIndent == null && (block == null || block.StartLocation.Line < t.Line))
                        {
                            lastLineIndent = block;
                        }

                        if (t.Kind == DTokens.CloseParenthesis &&
                            block != null &&
                            block.BlockStartToken == DTokens.OpenParenthesis &&
                            la.Kind != DTokens.OpenCurlyBrace)
                        {
                            block = block.previousBlock;

                            continue;
                        }
                        else
                        {
                            PopBlock();
                        }

                        if (t.Kind == DTokens.CloseParenthesis &&
                            block != null &&
                            block.BlockStartToken == DTokens.OpenParenthesis)
                        {
                            if (la.Kind == DTokens.OpenCurlyBrace && la.Line > t.Line)
                            {
                                PopBlock();
                            }
                            else if (block != null && block.LastPreBlockIdentifier != null && IsPreStatementToken(block.LastPreBlockIdentifier.Kind))
                            {
                                block = block.previousBlock;
                            }
                        }
                    }
                }

                else if ((DParser.IsAttributeSpecifier(t.Kind, la.Kind) && la.Kind == DTokens.Colon) || t.Kind == DTokens.Case || t.Kind == DTokens.Default)
                {
                    while (block != null && block.BlockStartToken != DTokens.OpenCurlyBrace)
                    {
                        PopBlock();
                    }

                    PushBlock().Reason = CodeBlock.IndentReason.StatementLabel;

                    HadCaseStatementBegin = true;
                }
                else if (t.Kind == DTokens.Colon)
                {
                    if (HadCaseStatementBegin)
                    {
                        while (block != null && block.Reason != CodeBlock.IndentReason.StatementLabel)
                        {
                            PopBlock();
                        }
                        HadCaseStatementBegin = false;
                    }
                }

                // Don't indent these in front of function bodies
                else if (t.Kind == DTokens.In || t.Kind == DTokens.Out || t.Kind == DTokens.Body)
                {
                    if (block != null && block.Reason == CodeBlock.IndentReason.UnfinishedStatement)
                    {
                        PopBlock();
                    }
                }


                else if (block == null ||
                         block.Reason != CodeBlock.IndentReason.UnfinishedStatement &&
                         block.Reason != CodeBlock.IndentReason.SingleLineStatement)
                {
                    PushBlock().Reason = CodeBlock.IndentReason.UnfinishedStatement;
                }
            }

            if (t != null && la.Line > t.Line)
            {
                RemoveNextLineUnindentBlocks();
            }

            return(lastLineIndent ?? block);
        }