diff options
author | Daniel Jasper <djasper@google.com> | 2015-02-20 13:47:38 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2015-02-20 13:47:38 +0000 |
commit | a0ef4f36c85565a703fcd533ab2958e238d62421 (patch) | |
tree | 5c644ceeeced83c66b5674c831ee5434ef8dce0f /clang/lib/Format | |
parent | ca1ba4b280998d54a9668473d8fb35c8fafed377 (diff) | |
download | bcm5719-llvm-a0ef4f36c85565a703fcd533ab2958e238d62421.tar.gz bcm5719-llvm-a0ef4f36c85565a703fcd533ab2958e238d62421.zip |
clang-format: [js] Support template strings.
Merge template strings (marked by backticks ``).
Do not format any contents of template strings.
Patch by Martin Probst. Thank you.
llvm-svn: 230011
Diffstat (limited to 'clang/lib/Format')
-rw-r--r-- | clang/lib/Format/Format.cpp | 66 | ||||
-rw-r--r-- | clang/lib/Format/FormatToken.h | 1 |
2 files changed, 66 insertions, 1 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index fad9e480fc5..3a0b7c09381 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -617,7 +617,7 @@ public: do { Tokens.push_back(getNextToken()); tryMergePreviousTokens(); - if (Tokens.back()->NewlinesBefore > 0) + if (Tokens.back()->NewlinesBefore > 0 || Tokens.back()->IsMultiline) FirstInLineIndex = Tokens.size() - 1; } while (Tokens.back()->Tok.isNot(tok::eof)); return Tokens; @@ -639,6 +639,8 @@ private: return; if (tryMergeEscapeSequence()) return; + if (tryMergeTemplateString()) + return; static tok::TokenKind JSIdentity[] = {tok::equalequal, tok::equal}; static tok::TokenKind JSNotIdentity[] = {tok::exclaimequal, tok::equal}; @@ -779,6 +781,66 @@ private: return false; } + bool tryMergeTemplateString() { + if (Tokens.size() < 2) + return false; + + FormatToken *EndBacktick = Tokens.back(); + if (!(EndBacktick->is(tok::unknown) && EndBacktick->TokenText == "`")) + return false; + + unsigned TokenCount = 0; + bool IsMultiline = false; + unsigned EndColumnInFirstLine = 0; + for (auto I = Tokens.rbegin() + 1, E = Tokens.rend(); I != E; I++) { + ++TokenCount; + if (I[0]->NewlinesBefore > 0 || I[0]->IsMultiline) + IsMultiline = true; + + // If there was a preceding template string, this must be the start of a + // template string, not the end. + if (I[0]->is(TT_TemplateString)) + return false; + + if (I[0]->isNot(tok::unknown) || I[0]->TokenText != "`") { + // Keep track of the rhs offset of the last token to wrap across lines - + // its the rhs offset of the first line of the template string, used to + // determine its width. + if (I[0]->IsMultiline) + EndColumnInFirstLine = I[0]->OriginalColumn + I[0]->ColumnWidth; + // If the token has newlines, the token before it (if it exists) is the + // rhs end of the previous line. + if (I[0]->NewlinesBefore > 0 && (I + 1 != E)) + EndColumnInFirstLine = I[1]->OriginalColumn + I[1]->ColumnWidth; + + continue; + } + + Tokens.resize(Tokens.size() - TokenCount); + Tokens.back()->Type = TT_TemplateString; + const char *EndOffset = EndBacktick->TokenText.data() + 1; + Tokens.back()->TokenText = + StringRef(Tokens.back()->TokenText.data(), + EndOffset - Tokens.back()->TokenText.data()); + if (IsMultiline) { + // ColumnWidth is from backtick to last token in line. + // LastLineColumnWidth is 0 to backtick. + // x = `some content + // until here`; + Tokens.back()->ColumnWidth = + EndColumnInFirstLine - Tokens.back()->OriginalColumn; + Tokens.back()->LastLineColumnWidth = EndBacktick->OriginalColumn; + Tokens.back()->IsMultiline = true; + } else { + // Token simply spans from start to end, +1 for the ` itself. + Tokens.back()->ColumnWidth = + EndBacktick->OriginalColumn - Tokens.back()->OriginalColumn + 1; + } + return true; + } + return false; + } + bool tryMerge_TMacro() { if (Tokens.size() < 4) return false; @@ -913,6 +975,8 @@ private: // Consume and record whitespace until we find a significant token. unsigned WhitespaceLength = TrailingWhitespace; while (FormatTok->Tok.is(tok::unknown)) { + // FIXME: This miscounts tok:unknown tokens that are not just + // whitespace, e.g. a '`' character. for (int i = 0, e = FormatTok->TokenText.size(); i != e; ++i) { switch (FormatTok->TokenText[i]) { case '\n': diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 559f9105bfd..14f45a44554 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -70,6 +70,7 @@ enum TokenType { TT_StartOfName, TT_TemplateCloser, TT_TemplateOpener, + TT_TemplateString, TT_TrailingAnnotation, TT_TrailingReturnArrow, TT_TrailingUnaryOperator, |