blob: fc6105469085db6435d1f49f0ea3cfbcedf617eb [file] [log] [blame]
Daniel Jasper0df50932014-12-10 19:00:42 +00001//===--- UnwrappedLineFormatter.h - Format C++ code -------------*- C++ -*-===//
2//
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 Implements a combinartorial exploration of all the different
12/// linebreaks unwrapped lines can be formatted in.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEFORMATTER_H
17#define LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEFORMATTER_H
18
19#include "ContinuationIndenter.h"
20#include "clang/Format/Format.h"
21#include <map>
22#include <queue>
23#include <string>
24
25namespace clang {
26namespace format {
27
28class ContinuationIndenter;
29class WhitespaceManager;
30
31class UnwrappedLineFormatter {
32public:
33 UnwrappedLineFormatter(ContinuationIndenter *Indenter,
34 WhitespaceManager *Whitespaces,
Nico Weberfac23712015-02-04 15:26:27 +000035 const FormatStyle &Style,
Manuel Klimekec5c3db2015-05-07 12:26:30 +000036 const AdditionalKeywords &Keywords,
37 bool *IncompleteFormat)
Nico Weberfac23712015-02-04 15:26:27 +000038 : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style),
Manuel Klimekec5c3db2015-05-07 12:26:30 +000039 Keywords(Keywords), IncompleteFormat(IncompleteFormat) {}
Daniel Jasper0df50932014-12-10 19:00:42 +000040
Manuel Klimekd3585db2015-05-11 08:21:35 +000041 /// \brief Format the current block and return the penalty.
42 unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines,
43 bool DryRun = false, int AdditionalIndent = 0,
44 bool FixBadIndentation = false);
Daniel Jasper289afc02015-04-23 09:23:17 +000045
Daniel Jasper0df50932014-12-10 19:00:42 +000046private:
Daniel Jasper0df50932014-12-10 19:00:42 +000047 /// \brief Get the offset of the line relatively to the level.
48 ///
49 /// For example, 'public:' labels in classes are offset by 1 or 2
50 /// characters to the left from their level.
51 int getIndentOffset(const FormatToken &RootToken) {
Daniel Jasper83709082015-02-18 17:14:05 +000052 if (Style.Language == FormatStyle::LK_Java ||
53 Style.Language == FormatStyle::LK_JavaScript)
Daniel Jasper0df50932014-12-10 19:00:42 +000054 return 0;
Daniel Jasper53395402015-04-07 15:04:40 +000055 if (RootToken.isAccessSpecifier(false) ||
Daniel Jasper03618142015-05-06 19:21:23 +000056 RootToken.isObjCAccessSpecifier() ||
57 (RootToken.is(Keywords.kw_signals) && RootToken.Next &&
58 RootToken.Next->is(tok::colon)))
Daniel Jasper0df50932014-12-10 19:00:42 +000059 return Style.AccessModifierOffset;
60 return 0;
61 }
62
63 /// \brief Add a new line and the required indent before the first Token
64 /// of the \c UnwrappedLine if there was no structural parsing error.
65 void formatFirstToken(FormatToken &RootToken,
66 const AnnotatedLine *PreviousLine, unsigned IndentLevel,
67 unsigned Indent, bool InPPDirective);
68
69 /// \brief Get the indent of \p Level from \p IndentForLevel.
70 ///
71 /// \p IndentForLevel must contain the indent for the level \c l
72 /// at \p IndentForLevel[l], or a value < 0 if the indent for
73 /// that level is unknown.
74 unsigned getIndent(ArrayRef<int> IndentForLevel, unsigned Level);
75
76 void join(AnnotatedLine &A, const AnnotatedLine &B);
77
78 unsigned getColumnLimit(bool InPPDirective) const {
79 // In preprocessor directives reserve two chars for trailing " \"
80 return Style.ColumnLimit - (InPPDirective ? 2 : 0);
81 }
82
Daniel Jasper0df50932014-12-10 19:00:42 +000083 // Cache to store the penalty of formatting a vector of AnnotatedLines
84 // starting from a specific additional offset. Improves performance if there
85 // are many nested blocks.
86 std::map<std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned>,
87 unsigned> PenaltyCache;
Manuel Klimekec5c3db2015-05-07 12:26:30 +000088
Manuel Klimekd3585db2015-05-11 08:21:35 +000089 ContinuationIndenter *Indenter;
90 WhitespaceManager *Whitespaces;
91 const FormatStyle &Style;
92 const AdditionalKeywords &Keywords;
Manuel Klimekec5c3db2015-05-07 12:26:30 +000093 bool *IncompleteFormat;
Daniel Jasper0df50932014-12-10 19:00:42 +000094};
95} // end namespace format
96} // end namespace clang
97
98#endif // LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEFORMATTER_H