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; } }
CodeBlock PushBlock(CodeBlock previousBlock=null) { return block = new CodeBlock { previousBlock=previousBlock, LastPreBlockIdentifier=Lexer.LastToken ?? null, Parent=block, StartLocation = t.Location }; }
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; }
CodeBlock PopBlock() { if (block != null) return block = block.Parent; return null; }
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); }