From f69b922e571669f72a9b3c0a6655c08da0be973b Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Sat, 2 May 2015 08:05:38 +0000 Subject: [PATCH] clang-format: [JS] Fix calculation of template string width. OriginalColumn might not be set, so fall back to Location and SourceMgr in case it is missing. Also initialize end column in case the token is multi line, but it's the ` token itself that starts the multi line. Patch by Martin Probst, thank you! llvm-svn: 236383 --- clang/lib/Format/Format.cpp | 18 ++++++++++++++---- clang/unittests/Format/FormatTestJS.cpp | 6 ++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 2333b2366a24..eabdaca5f345 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -782,7 +782,7 @@ private: return false; FormatToken *EndBacktick = Tokens.back(); - // Backticks get lexed as tok:unknown tokens. If a template string contains + // Backticks get lexed as tok::unknown tokens. If a template string contains // a comment start, it gets lexed as a tok::comment, or tok::unknown if // unterminated. if (!EndBacktick->isOneOf(tok::comment, tok::unknown)) @@ -795,7 +795,8 @@ private: unsigned TokenCount = 0; bool IsMultiline = false; - unsigned EndColumnInFirstLine = 0; + unsigned EndColumnInFirstLine = + EndBacktick->OriginalColumn + EndBacktick->ColumnWidth; for (auto I = Tokens.rbegin() + 1, E = Tokens.rend(); I != E; I++) { ++TokenCount; if (I[0]->NewlinesBefore > 0 || I[0]->IsMultiline) @@ -833,6 +834,15 @@ private: Tokens.back()->TokenText = StringRef(Tokens.back()->TokenText.data(), EndOffset - Tokens.back()->TokenText.data()); + + unsigned EndOriginalColumn = EndBacktick->OriginalColumn; + if (EndOriginalColumn == 0) { + SourceLocation Loc = EndBacktick->Tok.getLocation(); + EndOriginalColumn = SourceMgr.getSpellingColumnNumber(Loc); + } + // If the ` is further down within the token (e.g. in a comment). + EndOriginalColumn += CommentBacktickPos; + if (IsMultiline) { // ColumnWidth is from backtick to last token in line. // LastLineColumnWidth is 0 to backtick. @@ -840,12 +850,12 @@ private: // until here`; Tokens.back()->ColumnWidth = EndColumnInFirstLine - Tokens.back()->OriginalColumn; - Tokens.back()->LastLineColumnWidth = EndBacktick->OriginalColumn; + Tokens.back()->LastLineColumnWidth = EndOriginalColumn; 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; + EndOriginalColumn - Tokens.back()->OriginalColumn + 1; } return true; } diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index e0719ee4fc23..a7d8dd3effa6 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -646,6 +646,12 @@ TEST_F(FormatTestJS, TemplateStrings) { "var x =\n `multi\n line`;", format("var x = `multi\n line`;", getGoogleJSStyleWithColumns(14 - 1))); + // Make sure template strings get a proper ColumnWidth assigned, even if they + // are first token in line. + verifyFormat( + "var a = aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" + " `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;"); + // Two template strings. verifyFormat("var x = `hello` == `hello`;");