summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucie Gerard <lucie.gerard@qt.io>2019-04-01 10:23:38 +0200
committerLucie Gerard <lucie.gerard@qt.io>2019-04-01 12:23:45 +0000
commitd9aebed5c8520911f290da0d66b6cb849ccb9657 (patch)
tree4d22d73318413caf8c3d145d54cea7af92f204d9
parent50335cb26bb88930f5e2a204642439cc9a4d2282 (diff)
downloadqttools-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.cpp25
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result24
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"/>