summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/linguist/lupdate/python.cpp55
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsepython/main.py10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsepython/project.ts.result13
3 files changed, 48 insertions, 30 deletions
diff --git a/src/linguist/lupdate/python.cpp b/src/linguist/lupdate/python.cpp
index f1de3b0ac..4a7966578 100644
--- a/src/linguist/lupdate/python.cpp
+++ b/src/linguist/lupdate/python.cpp
@@ -24,7 +24,7 @@ static const char PythonMagicComment[] = "TRANSLATOR ";
most of Python; the only tokens that interest us are defined here.
*/
-enum Token { Tok_Eof, Tok_class, Tok_return, Tok_tr,
+enum Token { Tok_Eof, Tok_class, Tok_def, Tok_return, Tok_tr,
Tok_trUtf8, Tok_translate, Tok_Ident,
Tok_Comment, Tok_Dot, Tok_String,
Tok_LeftParen, Tok_RightParen,
@@ -51,6 +51,7 @@ static QByteArray id;
QHash<QByteArray, Token> tokens = {
{"None", Tok_None},
{"class", Tok_class},
+ {"def", Tok_def},
{"return", Tok_return},
{"__tr", Tok_tr}, // Legacy?
{"__trUtf8", Tok_trUtf8}
@@ -76,8 +77,6 @@ using ContextPair = QPair<QByteArray, int>;
using ContextStack = QStack<ContextPair>;
static ContextStack yyContextStack;
-static int yyContextPops;
-
static int getCharFromFile()
{
int c;
@@ -95,17 +94,6 @@ static int getCharFromFile()
} else if (yyCountingIndentation && (c == 32 || c == 9)) {
yyContinuousSpaceCount++;
} else {
- if (yyIndentationSize == 1 && yyContinuousSpaceCount > yyIndentationSize)
- yyIndentationSize = yyContinuousSpaceCount;
- if (yyCountingIndentation && yyContextStack.size() > 1) {
- ContextPair& top = yyContextStack.top();
- if (top.second == 0 && yyContinuousSpaceCount > 0) {
- top.second = yyContinuousSpaceCount;
- yyContinuousSpaceCount = 0;
- } else if (yyContinuousSpaceCount < top.second) {
- yyContextPops = (top.second - yyContinuousSpaceCount) / yyIndentationSize;
- }
- }
yyCountingIndentation = false;
}
return c;
@@ -131,11 +119,10 @@ static void startTokenizer(const QString &fileName, int (*getCharFunc)(),
yyParenDepth = 0;
yyCurLineNo = 1;
- yyIndentationSize = 1;
+ yyIndentationSize = -1;
yyContinuousSpaceCount = 0;
yyCountingIndentation = false;
yyContextStack.clear();
- yyContextPops = 0;
}
static Token parseString()
@@ -566,22 +553,33 @@ static void parse(Translator &tor, ConversionData &cd,
QByteArray prefix;
bool utf8 = false;
- yyContextStack.push({initialContext, 0});
-
yyTok = getToken();
while (yyTok != Tok_Eof) {
- if (yyContextPops > 0) {
- for ( int i = 0; i < yyContextPops; i++)
- yyContextStack.pop();
- yyContextPops = 0;
- }
-
switch (yyTok) {
- case Tok_class:
+ case Tok_class: {
+ if (yyIndentationSize < 0 && yyContinuousSpaceCount > 0)
+ yyIndentationSize = yyContinuousSpaceCount; // First indented "class"
+ const int indent = yyIndentationSize > 0
+ ? yyContinuousSpaceCount / yyIndentationSize : 0;
+ while (!yyContextStack.isEmpty() && yyContextStack.top().second >= indent)
+ yyContextStack.pop();
+ yyTok = getToken();
+ yyContextStack.push({yyIdent, indent});
yyTok = getToken();
- yyContextStack.push({yyIdent, 0});
- yyContinuousSpaceCount = 0;
+ }
+ break;
+ case Tok_def:
+ if (yyIndentationSize < 0 && yyContinuousSpaceCount > 0)
+ yyIndentationSize = yyContinuousSpaceCount; // First indented "def"
+ if (!yyContextStack.isEmpty()) {
+ // Pop classes if the function is further outdented than the class on the top
+ // (end of a nested class).
+ const int classIndent = yyIndentationSize > 0
+ ? yyContinuousSpaceCount / yyIndentationSize - 1 : 0;
+ while (!yyContextStack.isEmpty() && yyContextStack.top().second > classIndent)
+ yyContextStack.pop();
+ }
yyTok = getToken();
break;
case Tok_tr:
@@ -607,7 +605,8 @@ static void parse(Translator &tor, ConversionData &cd,
if (prefix.isEmpty())
context = defaultContext;
else if (prefix == "self")
- context = yyContextStack.top().first;
+ context = yyContextStack.isEmpty()
+ ? initialContext : yyContextStack.top().first;
else
context = prefix;
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsepython/main.py b/tests/auto/linguist/lupdate/testdata/good/parsepython/main.py
index 6375ff4da..e2bf9ac93 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsepython/main.py
+++ b/tests/auto/linguist/lupdate/testdata/good/parsepython/main.py
@@ -5,10 +5,10 @@ from PySide6.QtCore import (QItemSelection, QLibraryInfo, QLocale, QTranslator,
Qt, Slot)
from PySide6.QtWidgets import (QAbstractItemView, QApplication, QListWidget,
QMainWindow, QWidget)
-
-
import linguist_rc
+""""
+ Misleading indentation (5) for PYSIDE-2379"""
class Window(QMainWindow):
def __init__(self):
@@ -66,6 +66,12 @@ class Window(QMainWindow):
"THIS SHOULD NOT WORK"
)
+ class NestedClass:
+ def foo(self):
+ msg = self.tr("Nested Message")
+
+ def window_method(self): # PYSIDE-2379, Don't put this into NestedClass
+ msg = self.tr("Window Message")
if __name__ == '__main__':
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsepython/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsepython/project.ts.result
index f081bc23a..658485339 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsepython/project.ts.result
+++ b/tests/auto/linguist/lupdate/testdata/good/parsepython/project.ts.result
@@ -38,6 +38,14 @@
</message>
</context>
<context>
+ <name>NestedClass</name>
+ <message>
+ <location filename="main.py" line="73"/>
+ <source>Nested Message</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>Window</name>
<message>
<location filename="main.py" line="17"/>
@@ -72,5 +80,10 @@
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <location filename="main.py" line="77"/>
+ <source>Window Message</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
</TS>