diff options
author | Martin Probst <martin@probst.io> | 2019-03-19 12:28:41 +0000 |
---|---|---|
committer | Martin Probst <martin@probst.io> | 2019-03-19 12:28:41 +0000 |
commit | 6e5c5ff2d98f297fcfbb107f00010b792c4a8b14 (patch) | |
tree | 1eeeeb9dd8b6fae467b0067b85b4952db6740cc2 /lib/Format | |
parent | e40a5a512cae6848aa78ddf8194f1ef1fa0798e2 (diff) |
[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!).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356449 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format')
-rw-r--r-- | lib/Format/FormatToken.h | 1 | ||||
-rw-r--r-- | lib/Format/FormatTokenLexer.cpp | 21 | ||||
-rw-r--r-- | lib/Format/FormatTokenLexer.h | 1 |
3 files changed, 23 insertions, 0 deletions
diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h index 2989c760b6..a5daf8aed4 100644 --- a/lib/Format/FormatToken.h +++ b/lib/Format/FormatToken.h @@ -60,6 +60,7 @@ namespace format { TYPE(JsExponentiationEqual) \ TYPE(JsFatArrow) \ TYPE(JsNonNullAssertion) \ + TYPE(JsPrivateIdentifier) \ TYPE(JsTypeColon) \ TYPE(JsTypeOperator) \ TYPE(JsTypeOptionalQuestion) \ diff --git a/lib/Format/FormatTokenLexer.cpp b/lib/Format/FormatTokenLexer.cpp index 2f1b08a8b0..da755e36c1 100644 --- a/lib/Format/FormatTokenLexer.cpp +++ b/lib/Format/FormatTokenLexer.cpp @@ -95,6 +95,8 @@ void FormatTokenLexer::tryMergePreviousTokens() { Tokens.back()->Tok.setKind(tok::starequal); return; } + if (tryMergeJSPrivateIdentifier()) + return; } if (Style.Language == FormatStyle::LK_Java) { @@ -121,6 +123,25 @@ bool FormatTokenLexer::tryMergeNSStringLiteral() { 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. if (Tokens.size() < 3) diff --git a/lib/Format/FormatTokenLexer.h b/lib/Format/FormatTokenLexer.h index 61a4c041d1..a964626146 100644 --- a/lib/Format/FormatTokenLexer.h +++ b/lib/Format/FormatTokenLexer.h @@ -48,6 +48,7 @@ private: bool tryMergeLessLess(); bool tryMergeNSStringLiteral(); + bool tryMergeJSPrivateIdentifier(); bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, TokenType NewType); |