TokenAnnotator.h revision 263508
11590Srgrimes//===--- TokenAnnotator.h - Format C++ code ---------------------*- C++ -*-===//
21590Srgrimes//
31590Srgrimes//                     The LLVM Compiler Infrastructure
41590Srgrimes//
51590Srgrimes// This file is distributed under the University of Illinois Open Source
61590Srgrimes// License. See LICENSE.TXT for details.
71590Srgrimes//
81590Srgrimes//===----------------------------------------------------------------------===//
91590Srgrimes///
101590Srgrimes/// \file
111590Srgrimes/// \brief This file implements a token annotator, i.e. creates
121590Srgrimes/// \c AnnotatedTokens out of \c FormatTokens with required extra information.
131590Srgrimes///
141590Srgrimes//===----------------------------------------------------------------------===//
151590Srgrimes
161590Srgrimes#ifndef LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
171590Srgrimes#define LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
181590Srgrimes
191590Srgrimes#include "UnwrappedLineParser.h"
201590Srgrimes#include "clang/Format/Format.h"
211590Srgrimes#include <string>
221590Srgrimes
231590Srgrimesnamespace clang {
241590Srgrimesclass SourceManager;
251590Srgrimes
261590Srgrimesnamespace format {
271590Srgrimes
281590Srgrimesenum LineType {
291590Srgrimes  LT_Invalid,
301590Srgrimes  LT_Other,
3174769Smikeh  LT_PreprocessorDirective,
321590Srgrimes  LT_VirtualFunctionDecl,
3374769Smikeh  LT_ObjCDecl, // An @interface, @implementation, or @protocol line.
341590Srgrimes  LT_ObjCMethodDecl,
3599112Sobrien  LT_ObjCProperty // An @property line.
3699112Sobrien};
371590Srgrimes
3891227Sbdeclass AnnotatedLine {
3991227Sbdepublic:
401590Srgrimes  AnnotatedLine(const UnwrappedLine &Line)
411590Srgrimes      : First(Line.Tokens.front().Tok), Level(Line.Level),
421590Srgrimes        InPPDirective(Line.InPPDirective),
431590Srgrimes        MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
441590Srgrimes        StartsDefinition(false) {
451590Srgrimes    assert(!Line.Tokens.empty());
461590Srgrimes
471590Srgrimes    // Calculate Next and Previous for all tokens. Note that we must overwrite
481590Srgrimes    // Next and Previous for every token, as previous formatting runs might have
4992921Simp    // left them in a different state.
5077274Smikeh    First->Previous = NULL;
511590Srgrimes    FormatToken *Current = First;
521590Srgrimes    for (std::list<UnwrappedLineNode>::const_iterator I = ++Line.Tokens.begin(),
531590Srgrimes                                                      E = Line.Tokens.end();
541590Srgrimes         I != E; ++I) {
55216564Scharnier      const UnwrappedLineNode &Node = *I;
561590Srgrimes      Current->Next = I->Tok;
571590Srgrimes      I->Tok->Previous = Current;
581590Srgrimes      Current = Current->Next;
591590Srgrimes      Current->Children.clear();
6077274Smikeh      for (SmallVectorImpl<UnwrappedLine>::const_iterator
611590Srgrimes               I = Node.Children.begin(),
6277274Smikeh               E = Node.Children.end();
631590Srgrimes           I != E; ++I) {
641590Srgrimes        Children.push_back(new AnnotatedLine(*I));
651590Srgrimes        Current->Children.push_back(Children.back());
661590Srgrimes      }
671590Srgrimes    }
68173438Sdds    Last = Current;
69216564Scharnier    Last->Next = NULL;
701590Srgrimes  }
711590Srgrimes
721590Srgrimes  ~AnnotatedLine() {
731590Srgrimes    for (unsigned i = 0, e = Children.size(); i != e; ++i) {
741590Srgrimes      delete Children[i];
7577274Smikeh    }
761590Srgrimes  }
771590Srgrimes
781590Srgrimes  FormatToken *First;
791590Srgrimes  FormatToken *Last;
801590Srgrimes
811590Srgrimes  SmallVector<AnnotatedLine *, 0> Children;
8277274Smikeh
831590Srgrimes  LineType Type;
841590Srgrimes  unsigned Level;
851590Srgrimes  bool InPPDirective;
861590Srgrimes  bool MustBeDeclaration;
871590Srgrimes  bool MightBeFunctionDecl;
881590Srgrimes  bool StartsDefinition;
891590Srgrimes
901590Srgrimesprivate:
91216564Scharnier  // Disallow copying.
921590Srgrimes  AnnotatedLine(const AnnotatedLine &) LLVM_DELETED_FUNCTION;
931590Srgrimes  void operator=(const AnnotatedLine &) LLVM_DELETED_FUNCTION;
941590Srgrimes};
951590Srgrimes
961590Srgrimes/// \brief Determines extra information about the tokens comprising an
971590Srgrimes/// \c UnwrappedLine.
981590Srgrimesclass TokenAnnotator {
991590Srgrimespublic:
1001590Srgrimes  TokenAnnotator(const FormatStyle &Style, IdentifierInfo &Ident_in)
1011590Srgrimes      : Style(Style), Ident_in(Ident_in) {}
1021590Srgrimes
1031590Srgrimes  /// \brief Adapts the indent levels of comment lines to the indent of the
104216564Scharnier  /// subsequent line.
1051590Srgrimes  // FIXME: Can/should this be done in the UnwrappedLineParser?
1061590Srgrimes  void setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines);
1071590Srgrimes
1081590Srgrimes  void annotate(AnnotatedLine &Line);
10977274Smikeh  void calculateFormattingInformation(AnnotatedLine &Line);
11077274Smikeh
1111590Srgrimesprivate:
1121590Srgrimes  /// \brief Calculate the penalty for splitting before \c Tok.
1131590Srgrimes  unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok,
1141590Srgrimes                        bool InFunctionDecl);
1151590Srgrimes
1161590Srgrimes  bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left,
117216564Scharnier                            const FormatToken &Right);
1181590Srgrimes
11977274Smikeh  bool spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Tok);
1201590Srgrimes
12177274Smikeh  bool mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right);
1228874Srgrimes
12377274Smikeh  bool canBreakBefore(const AnnotatedLine &Line, const FormatToken &Right);
1241590Srgrimes
1251590Srgrimes  void printDebugInfo(const AnnotatedLine &Line);
1261590Srgrimes
1271590Srgrimes  void calculateUnbreakableTailLengths(AnnotatedLine &Line);
12877274Smikeh
1291590Srgrimes  const FormatStyle &Style;
1301590Srgrimes
131216564Scharnier  // Contextual keywords:
1321590Srgrimes  IdentifierInfo &Ident_in;
13377274Smikeh};
1341590Srgrimes
13577274Smikeh} // end namespace format
13677274Smikeh} // end namespace clang
13777274Smikeh
1381590Srgrimes#endif // LLVM_CLANG_FORMAT_TOKEN_ANNOTATOR_H
1391590Srgrimes