r356449 - [clang-format] [JS] handle private members.
Martin Probst via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 19 05:28:41 PDT 2019
Author: mprobst
Date: Tue Mar 19 05:28:41 2019
New Revision: 356449
URL: http://llvm.org/viewvc/llvm-project?rev=356449&view=rev
Log:
[clang-format] [JS] handle private members.
Addresses PR40999 https://bugs.llvm.org/show_bug.cgi?id=40999
Private fields and methods in JavaScript would get incorrectly indented
(it sees them as preprocessor directives and hence left aligns them)
In this revision `#identifier` tokens `tok::hash->tok::identifier` are
merged into a single new token `tok::identifier` with the `#` contained
inside the TokenText.
Before:
```
class Example {
pub = 1;
static pub2 = "foo";
static #priv2 = "bar";
method() { this.#priv = 5; }
static staticMethod() {
switch (this.#priv) {
case '1':
break;
}
}
this.#privateMethod(); // infinite loop
}
static #staticPrivateMethod() {}
}
```
After this fix the code will be correctly indented
```
class Example {
pub = 1;
#priv = 2;
static pub2 = "foo";
static #priv2 = "bar";
method() { this.#priv = 5; }
static staticMethod() {
switch (this.#priv) {
case '1':
#priv = 3;
break;
}
}
#privateMethod() {
this.#privateMethod(); // infinite loop
}
static #staticPrivateMethod() {}
}
```
NOTE: There might be some JavaScript code out there which uses the C
processor to preprocess .js files
http://www.nongnu.org/espresso/js-cpp.html. It's not clear how this
revision or even private fields and methods would interact.
Patch originally by MyDeveloperDays (thanks!).
Modified:
cfe/trunk/lib/Format/FormatToken.h
cfe/trunk/lib/Format/FormatTokenLexer.cpp
cfe/trunk/lib/Format/FormatTokenLexer.h
cfe/trunk/unittests/Format/FormatTestJS.cpp
Modified: cfe/trunk/lib/Format/FormatToken.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=356449&r1=356448&r2=356449&view=diff
==============================================================================
--- cfe/trunk/lib/Format/FormatToken.h (original)
+++ cfe/trunk/lib/Format/FormatToken.h Tue Mar 19 05:28:41 2019
@@ -60,6 +60,7 @@ namespace format {
TYPE(JsExponentiationEqual) \
TYPE(JsFatArrow) \
TYPE(JsNonNullAssertion) \
+ TYPE(JsPrivateIdentifier) \
TYPE(JsTypeColon) \
TYPE(JsTypeOperator) \
TYPE(JsTypeOptionalQuestion) \
Modified: cfe/trunk/lib/Format/FormatTokenLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatTokenLexer.cpp?rev=356449&r1=356448&r2=356449&view=diff
==============================================================================
--- cfe/trunk/lib/Format/FormatTokenLexer.cpp (original)
+++ cfe/trunk/lib/Format/FormatTokenLexer.cpp Tue Mar 19 05:28:41 2019
@@ -95,6 +95,8 @@ void FormatTokenLexer::tryMergePreviousT
Tokens.back()->Tok.setKind(tok::starequal);
return;
}
+ if (tryMergeJSPrivateIdentifier())
+ return;
}
if (Style.Language == FormatStyle::LK_Java) {
@@ -120,6 +122,25 @@ bool FormatTokenLexer::tryMergeNSStringL
Tokens.erase(Tokens.end() - 1);
return true;
}
+
+bool FormatTokenLexer::tryMergeJSPrivateIdentifier() {
+ // Merges #idenfier into a single identifier with the text #identifier
+ // but the token tok::identifier.
+ if (Tokens.size() < 2)
+ return false;
+ auto &Hash = *(Tokens.end() - 2);
+ auto &Identifier = *(Tokens.end() - 1);
+ if (!Hash->is(tok::hash) || !Identifier->is(tok::identifier))
+ return false;
+ Hash->Tok.setKind(tok::identifier);
+ Hash->TokenText =
+ StringRef(Hash->TokenText.begin(),
+ Identifier->TokenText.end() - Hash->TokenText.begin());
+ Hash->ColumnWidth += Identifier->ColumnWidth;
+ Hash->Type = TT_JsPrivateIdentifier;
+ Tokens.erase(Tokens.end() - 1);
+ return true;
+}
bool FormatTokenLexer::tryMergeLessLess() {
// Merge X,less,less,Y into X,lessless,Y unless X or Y is less.
Modified: cfe/trunk/lib/Format/FormatTokenLexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatTokenLexer.h?rev=356449&r1=356448&r2=356449&view=diff
==============================================================================
--- cfe/trunk/lib/Format/FormatTokenLexer.h (original)
+++ cfe/trunk/lib/Format/FormatTokenLexer.h Tue Mar 19 05:28:41 2019
@@ -48,6 +48,7 @@ private:
bool tryMergeLessLess();
bool tryMergeNSStringLiteral();
+ bool tryMergeJSPrivateIdentifier();
bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, TokenType NewType);
Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=356449&r1=356448&r2=356449&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestJS.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp Tue Mar 19 05:28:41 2019
@@ -2334,5 +2334,27 @@ TEST_F(FormatTestJS, ConditionalTypes) {
" never) extends((k: infer I) => void) ? I : never;");
}
-} // end namespace tooling
+TEST_F(FormatTestJS, SupportPrivateFieldsAndMethods) {
+ verifyFormat("class Example {\n"
+ " pub = 1;\n"
+ " #priv = 2;\n"
+ " static pub2 = 'foo';\n"
+ " static #priv2 = 'bar';\n"
+ " method() {\n"
+ " this.#priv = 5;\n"
+ " }\n"
+ " static staticMethod() {\n"
+ " switch (this.#priv) {\n"
+ " case '1':\n"
+ " #priv = 3;\n"
+ " break;\n"
+ " }\n"
+ " }\n"
+ " #privateMethod() {\n"
+ " this.#privateMethod(); // infinite loop\n"
+ " }\n"
+ " static #staticPrivateMethod() {}\n");
+}
+
+} // namespace format
} // end namespace clang
More information about the cfe-commits
mailing list