diff options
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> |