blob: ccf437f50744b1b5ae245f75019c6b52eab1743e [file] [log] [blame]
Chandler Carruth55fc8732012-12-04 09:13:33 +00001//===--- UnwrappedLineParser.h - Format C++ code ----------------*- C++ -*-===//
Daniel Jasperbac016b2012-12-03 18:12:45 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file contains the declaration of the UnwrappedLineParser,
12/// which turns a stream of tokens into UnwrappedLines.
13///
14/// This is EXPERIMENTAL code under heavy development. It is not in a state yet,
15/// where it can be used to format real code.
16///
17//===----------------------------------------------------------------------===//
18
19#ifndef LLVM_CLANG_FORMAT_UNWRAPPED_LINE_PARSER_H
20#define LLVM_CLANG_FORMAT_UNWRAPPED_LINE_PARSER_H
21
Daniel Jasperbac016b2012-12-03 18:12:45 +000022#include "clang/Basic/IdentifierTable.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000023#include "clang/Basic/SourceManager.h"
Alexander Kornienko15757312012-12-06 18:03:27 +000024#include "clang/Format/Format.h"
Daniel Jasperbac016b2012-12-03 18:12:45 +000025#include "clang/Lex/Lexer.h"
26
27namespace clang {
28namespace format {
29
30/// \brief A wrapper around a \c Token storing information about the
31/// whitespace characters preceeding it.
32struct FormatToken {
33 FormatToken() : NewlinesBefore(0), WhiteSpaceLength(0) {
34 }
35
36 /// \brief The \c Token.
37 Token Tok;
38
39 /// \brief The number of newlines immediately before the \c Token.
40 ///
41 /// This can be used to determine what the user wrote in the original code
42 /// and thereby e.g. leave an empty line between two function definitions.
43 unsigned NewlinesBefore;
44
45 /// \brief The location of the start of the whitespace immediately preceeding
46 /// the \c Token.
47 ///
48 /// Used together with \c WhiteSpaceLength to create a \c Replacement.
49 SourceLocation WhiteSpaceStart;
50
51 /// \brief The length in characters of the whitespace immediately preceeding
52 /// the \c Token.
53 unsigned WhiteSpaceLength;
54};
55
56/// \brief An unwrapped line is a sequence of \c Token, that we would like to
57/// put on a single line if there was no column limit.
58///
59/// This is used as a main interface between the \c UnwrappedLineParser and the
60/// \c UnwrappedLineFormatter. The key property is that changing the formatting
61/// within an unwrapped line does not affect any other unwrapped lines.
62struct UnwrappedLine {
63 UnwrappedLine() : Level(0) {
64 }
65
66 /// \brief The \c Token comprising this \c UnwrappedLine.
67 SmallVector<FormatToken, 16> Tokens;
68
69 /// \brief The indent level of the \c UnwrappedLine.
70 unsigned Level;
71};
72
73class UnwrappedLineConsumer {
74public:
Daniel Jasperaccb0b02012-12-04 21:05:31 +000075 virtual ~UnwrappedLineConsumer() {
76 }
Alexander Kornienko720ffb62012-12-05 13:56:52 +000077 virtual void consumeUnwrappedLine(const UnwrappedLine &Line) = 0;
Daniel Jasperbac016b2012-12-03 18:12:45 +000078};
79
Alexander Kornienko469a21b2012-12-07 16:15:44 +000080class FormatTokenSource {
81public:
Matt Beaumont-Gay422daa12012-12-07 22:49:27 +000082 virtual ~FormatTokenSource() {
83 }
Alexander Kornienko469a21b2012-12-07 16:15:44 +000084 virtual FormatToken getNextToken() = 0;
85};
86
Daniel Jasperbac016b2012-12-03 18:12:45 +000087class UnwrappedLineParser {
88public:
Alexander Kornienko469a21b2012-12-07 16:15:44 +000089 UnwrappedLineParser(const FormatStyle &Style, FormatTokenSource &Tokens,
Daniel Jasperbac016b2012-12-03 18:12:45 +000090 UnwrappedLineConsumer &Callback);
91
Alexander Kornienkocff563c2012-12-04 17:27:50 +000092 /// Returns true in case of a structural error.
93 bool parse();
Daniel Jasperbac016b2012-12-03 18:12:45 +000094
95private:
Alexander Kornienkocff563c2012-12-04 17:27:50 +000096 bool parseLevel();
Alexander Kornienko15757312012-12-06 18:03:27 +000097 bool parseBlock(unsigned AddLevels = 1);
Daniel Jasperbac016b2012-12-03 18:12:45 +000098 void parsePPDirective();
Daniel Jasper05b1ac82012-12-17 11:29:41 +000099 void parseComments();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000100 void parseStatement();
101 void parseParens();
102 void parseIfThenElse();
Alexander Kornienko2e97cfc2012-12-05 15:06:06 +0000103 void parseForOrWhileLoop();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000104 void parseDoWhile();
105 void parseLabel();
106 void parseCaseLabel();
107 void parseSwitch();
Alexander Kornienko15757312012-12-06 18:03:27 +0000108 void parseNamespace();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000109 void parseAccessSpecifier();
110 void parseEnum();
111 void addUnwrappedLine();
112 bool eof() const;
113 void nextToken();
Daniel Jasperbac016b2012-12-03 18:12:45 +0000114
115 UnwrappedLine Line;
116 FormatToken FormatTok;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000117
Alexander Kornienko15757312012-12-06 18:03:27 +0000118 const FormatStyle &Style;
Alexander Kornienko469a21b2012-12-07 16:15:44 +0000119 FormatTokenSource &Tokens;
Daniel Jasperbac016b2012-12-03 18:12:45 +0000120 UnwrappedLineConsumer &Callback;
121};
122
123} // end namespace format
124} // end namespace clang
125
Daniel Jasperd7610b82012-12-24 16:51:15 +0000126#endif // LLVM_CLANG_FORMAT_UNWRAPPED_LINE_PARSER_H