diff options
author | Lucie Gerard <lucie.gerard@qt.io> | 2019-04-01 10:23:38 +0200 |
---|---|---|
committer | Lucie Gerard <lucie.gerard@qt.io> | 2019-04-01 12:23:45 +0000 |
commit | d9aebed5c8520911f290da0d66b6cb849ccb9657 (patch) | |
tree | 4d22d73318413caf8c3d145d54cea7af92f204d9 | |
parent | 50335cb26bb88930f5e2a204642439cc9a4d2282 (diff) | |
download | qttools-d9aebed5c8520911f290da0d66b6cb849ccb9657.tar.gz |
Add forward looking after Colon
Colons seen are remembered in order to identify a member or base class
identifier.
In case of declaration of a bit field, the colon should be ignored.
If it is not, unexpected behaviors compromise the resolution of
the context, when the context is not explicit in the tr() function.
To differentiate between colons in a member or base class identifier,
and colons in a bit field, this patch implements a heuristic:
We parse forward to either a '{', or a ';'.
If it is a semicolon we assume it's a bit field, if it is a curved open
bracket we assume the colon is for a member or base class identifier.
Related auto test in case of bitfields declaration added.
Task-number: QTBUG-55479
Change-Id: I2ca1124c192e4ab16fd449afc634a5de5023f481
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
-rw-r--r-- | src/linguist/lupdate/cpp.cpp | 25 | ||||
-rw-r--r-- | tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp | 13 | ||||
-rw-r--r-- | tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result | 24 |
3 files changed, 60 insertions, 2 deletions
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp index aac9a90ff..d8a4f9a37 100644 --- a/src/linguist/lupdate/cpp.cpp +++ b/src/linguist/lupdate/cpp.cpp @@ -239,6 +239,7 @@ private: std::ostream &yyMsg(int line = 0); int getChar(); + TokenType lookAheadToSemicolonOrLeftBrace(); TokenType getToken(); void processComment(); @@ -450,6 +451,23 @@ int CppParser::getChar() } } +CppParser::TokenType CppParser::lookAheadToSemicolonOrLeftBrace() +{ + if (*yyInPtr == 0) + return Tok_Eof; + const ushort *uc = yyInPtr + 1; + forever { + ushort c = *uc; + if (!c) + return Tok_Eof; + if (c == ';') + return Tok_Semicolon; + if (c == '{') + return Tok_LeftBrace; + ++uc; + } +} + STRING(Q_OBJECT); STRING(class); STRING(final); @@ -2182,8 +2200,11 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac pendingContext = prospectiveContext; prospectiveContext.clear(); } - if (yyTok == Tok_Colon) - yyTokColonSeen = true; + //ignore colons for bitfields (are usually followed by a semicolon) + if (yyTok == Tok_Colon) { + if (lookAheadToSemicolonOrLeftBrace() != Tok_Semicolon) + yyTokColonSeen = true; + } } metaExpected = true; yyTok = getToken(); diff --git a/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp b/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp index 772ebfb29..6cef7a28c 100644 --- a/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp @@ -41,3 +41,16 @@ void Foo::bar() { tr("BAR"); } + +class BitFields : public QObject +{ + int bits : 20; + QString str = tr("text BitFields"); +}; + +Bibi::Bibi() +{ + int bits : 32; + tr("text Bibi"); + Babebi::tr("text Babebi"); +} diff --git a/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result index 7e7e27742..e4f347db2 100644 --- a/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result @@ -2,6 +2,30 @@ <!DOCTYPE TS> <TS version="2.1"> <context> + <name>Babebi</name> + <message> + <location filename="main.cpp" line="55"/> + <source>text Babebi</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Bibi</name> + <message> + <location filename="main.cpp" line="54"/> + <source>text Bibi</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>BitFields</name> + <message> + <location filename="main.cpp" line="48"/> + <source>text BitFields</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Foo</name> <message> <location filename="main.cpp" line="32"/> |