//===--- TokenAnnotator.cpp - Format C++ code -----------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a token annotator, i.e. creates
/// \c AnnotatedTokens out of \c FormatTokens with required extra information.
///
//===----------------------------------------------------------------------===//
#include "TokenAnnotator.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/Support/Debug.h"
namespace clang {
namespace format {
bool AnnotatedToken::isUnaryOperator() const {
switch (FormatTok.Tok.getKind()) {
case tok::plus:
case tok::plusplus:
case tok::minus:
case tok::minusminus:
case tok::exclaim:
case tok::tilde:
case tok::kw_sizeof:
case tok::kw_alignof:
return true;
default:
return false;
}
}
bool AnnotatedToken::isBinaryOperator() const {
// Comma is a binary operator, but does not behave as such wrt. formatting.
return getPrecedence(*this) > prec::Comma;
}
bool AnnotatedToken::isTrailingComment() const {
return is(tok::comment) &&
(Children.empty() || Children[0].FormatTok.NewlinesBefore > 0);
}
AnnotatedToken *AnnotatedToken::getPreviousNoneComment() const {
AnnotatedToken *Tok = Parent;
while (Tok != NULL && Tok->is(tok::comment))
Tok = Tok->Parent;
return Tok;
}
const AnnotatedToken *AnnotatedToken::getNextNoneComment() const {
const AnnotatedToken *Tok = Children.empty() ? NULL : &Children[0];
while (Tok != NULL && Tok->is(tok::comment))
Tok = Tok->Children.empty() ? NULL : &Tok->Children[0];
return Tok;
}
bool AnnotatedToken::closesScope() const {
return isOneOf(tok::r_paren, tok::r_brace, tok::r_square) ||
Type == TT_TemplateCloser;
}
bool AnnotatedToken::opensScope() const {
return isOneOf(tok::l_paren, tok::l_brace, tok::l_square) ||
Type == TT_TemplateOpener;
}
/// \brief A parser that gathers additional information about tokens.
///
/// The \c TokenAnnotator tries to match parenthesis and square brakets and
/// store a parenthesis levels. It also tries to resolve matching "<" and ">"
/// into template parameter lists.
class AnnotatingParser {
public:
AnnotatingParser(SourceManager &SourceMgr, Lexer &Lex, AnnotatedLine &Line,
IdentifierInfo &Ident_in)
: SourceMgr(SourceMgr), Lex(Lex), Line(Line), CurrentToken(&Line.First),
KeywordVirtualFound(false), NameFound(false), Ident_in(Ident_in) {
Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/ false));
}
private:
bool parseAngle() {
if (CurrentToken == NULL)
return false;
ScopedContextCreator ContextCreator(*this, tok::less,