summaryrefslogtreecommitdiffstats
path: root/clang/lib/Format
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2015-02-20 13:47:38 +0000
committerDaniel Jasper <djasper@google.com>2015-02-20 13:47:38 +0000
commita0ef4f36c85565a703fcd533ab2958e238d62421 (patch)
tree5c644ceeeced83c66b5674c831ee5434ef8dce0f /clang/lib/Format
parentca1ba4b280998d54a9668473d8fb35c8fafed377 (diff)
downloadbcm5719-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.cpp66
-rw-r--r--clang/lib/Format/FormatToken.h1
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,
OpenPOWER on IntegriCloud