MyDeveloperDay created this revision. MyDeveloperDay added reviewers: djasper, klimek, JonasToth, reuk, krasimir. MyDeveloperDay added a project: clang-tools-extra.
Addresses PR40999 https://bugs.llvm.org/show_bug.cgi?id=40999 Private fields and methods in javasceipt 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 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() {} } 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, Its not clear how this revision or even private fields and methods would interact. https://reviews.llvm.org/D59292 Files: clang/docs/ReleaseNotes.rst clang/lib/Format/FormatToken.h clang/lib/Format/FormatTokenLexer.cpp clang/lib/Format/FormatTokenLexer.h clang/unittests/Format/FormatTestJS.cpp
Index: clang/unittests/Format/FormatTestJS.cpp =================================================================== --- clang/unittests/Format/FormatTestJS.cpp +++ clang/unittests/Format/FormatTestJS.cpp @@ -2328,5 +2328,27 @@ " 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 Index: clang/lib/Format/FormatTokenLexer.h =================================================================== --- clang/lib/Format/FormatTokenLexer.h +++ clang/lib/Format/FormatTokenLexer.h @@ -48,6 +48,7 @@ bool tryMergeLessLess(); bool tryMergeNSStringLiteral(); + bool tryMergeJSPrivateIdentifier(); bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, TokenType NewType); Index: clang/lib/Format/FormatTokenLexer.cpp =================================================================== --- clang/lib/Format/FormatTokenLexer.cpp +++ clang/lib/Format/FormatTokenLexer.cpp @@ -95,6 +95,8 @@ Tokens.back()->Tok.setKind(tok::starequal); return; } + if (tryMergeJSPrivateIdentifier()) + return; } if (Style.Language == FormatStyle::LK_Java) { @@ -121,6 +123,25 @@ 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) Index: clang/lib/Format/FormatToken.h =================================================================== --- clang/lib/Format/FormatToken.h +++ clang/lib/Format/FormatToken.h @@ -63,6 +63,7 @@ TYPE(JsTypeColon) \ TYPE(JsTypeOperator) \ TYPE(JsTypeOptionalQuestion) \ + TYPE(JsPrivateIdentifier) \ TYPE(LambdaArrow) \ TYPE(LambdaLSquare) \ TYPE(LeadingJavaAnnotation) \ Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -171,7 +171,7 @@ ------------ -- ... +- Add support for correct indenting of private fields and methods in Javascript. libclang --------
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits