740 lines
43 KiB
Diff
740 lines
43 KiB
Diff
From e23fa8f15af89a8bd4bd84dd96b5fd7017457516 Mon Sep 17 00:00:00 2001
|
|
From: Francis Herne <mail@flherne.uk>
|
|
Date: Fri, 20 Sep 2019 00:41:29 +0100
|
|
Subject: Initial Python 3.8 support.
|
|
|
|
This allows kdev-python to be built and run against CPython 3.8,
|
|
and if so to parse files containing 3.8 syntax.
|
|
|
|
BUG: 411956
|
|
FIXED-IN: 5.5.0
|
|
---
|
|
CMakeLists.txt | 4 +-
|
|
duchain/declarationbuilder.cpp | 10 ++-
|
|
duchain/declarationbuilder.h | 1 +
|
|
duchain/expressionvisitor.cpp | 4 ++
|
|
duchain/expressionvisitor.h | 1 +
|
|
duchain/tests/pyduchaintest.cpp | 19 ++++++
|
|
parser/ast.cpp | 7 +-
|
|
parser/ast.h | 9 +++
|
|
parser/astbuilder.cpp | 6 ++
|
|
parser/astdefaultvisitor.cpp | 6 ++
|
|
parser/astdefaultvisitor.h | 2 +
|
|
parser/astvisitor.cpp | 1 +
|
|
parser/astvisitor.h | 1 +
|
|
parser/conversionGenerator.py | 11 +--
|
|
parser/generated.h | 36 ++++++++++
|
|
parser/python36.sdef | 102 ----------------------------
|
|
parser/python38.sdef | 145 ++++++++++++++++++++++++++++++++++++++++
|
|
parser/tests/pyasttest.cpp | 5 ++
|
|
18 files changed, 260 insertions(+), 110 deletions(-)
|
|
delete mode 100644 parser/python36.sdef
|
|
create mode 100644 parser/python38.sdef
|
|
|
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
index 6f9e465..09b089d 100644
|
|
--- a/CMakeLists.txt
|
|
+++ b/CMakeLists.txt
|
|
@@ -31,7 +31,7 @@ add_definitions( -DTRANSLATION_DOMAIN=\"kdevpython\" )
|
|
|
|
# CMake looks for exactly the specified version first and ignores newer versions.
|
|
# To avoid that, start looking for the newest supported version and work down.
|
|
-set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4)
|
|
+set(Python_ADDITIONAL_VERSIONS 3.8 3.7 3.6 3.5 3.4)
|
|
foreach(_PYTHON_V ${Python_ADDITIONAL_VERSIONS})
|
|
find_package(PythonInterp ${_PYTHON_V})
|
|
if ( PYTHONINTERP_FOUND )
|
|
@@ -49,7 +49,7 @@ if ( PYTHONINTERP_FOUND AND PYTHON_VERSION_STRING VERSION_GREATER "3.4" )
|
|
endif()
|
|
|
|
if ( NOT PYTHONLIBS_FOUND OR PYTHONLIBS_VERSION_STRING VERSION_LESS "3.4.3" )
|
|
- message(FATAL_ERROR "Python >= 3.4.3 but < 3.8 with --enable-shared is required to build kdev-python")
|
|
+ message(FATAL_ERROR "Python >= 3.4.3 but < 3.9 with --enable-shared is required to build kdev-python")
|
|
endif()
|
|
|
|
configure_file(kdevpythonversion.h.cmake "${CMAKE_CURRENT_BINARY_DIR}/kdevpythonversion.h" @ONLY)
|
|
diff --git a/duchain/declarationbuilder.cpp b/duchain/declarationbuilder.cpp
|
|
index e3cb2b9..61e144c 100644
|
|
--- a/duchain/declarationbuilder.cpp
|
|
+++ b/duchain/declarationbuilder.cpp
|
|
@@ -1354,6 +1354,14 @@ void DeclarationBuilder::visitAnnotationAssignment(AnnotationAssignmentAst* node
|
|
assignToUnknown(node->target, assignType);
|
|
}
|
|
|
|
+void DeclarationBuilder::visitAssignmentExpression(AssignmentExpressionAst* node) {
|
|
+ AstDefaultVisitor::visitAssignmentExpression(node);
|
|
+
|
|
+ ExpressionVisitor v(currentContext());
|
|
+ v.visitNode(node->value);
|
|
+ assignToUnknown(node->target, v.lastType());
|
|
+}
|
|
+
|
|
void DeclarationBuilder::visitClassDefinition( ClassDefinitionAst* node )
|
|
{
|
|
visitNodeList(node->decorators);
|
|
@@ -1745,7 +1753,7 @@ void DeclarationBuilder::visitArguments( ArgumentsAst* node )
|
|
int parametersCount = node->arguments.length();
|
|
int firstDefaultParameterOffset = parametersCount - defaultParametersCount;
|
|
int currentIndex = 0;
|
|
- foreach ( ArgAst* arg, node->arguments + node->kwonlyargs ) {
|
|
+ foreach ( ArgAst* arg, node->posonlyargs + node->arguments + node->kwonlyargs ) {
|
|
// Iterate over all the function's arguments, create declarations, and add the arguments
|
|
// to the functions FunctionType.
|
|
currentIndex += 1;
|
|
diff --git a/duchain/declarationbuilder.h b/duchain/declarationbuilder.h
|
|
index adee6d6..1992b78 100644
|
|
--- a/duchain/declarationbuilder.h
|
|
+++ b/duchain/declarationbuilder.h
|
|
@@ -90,6 +90,7 @@ protected:
|
|
void visitFunctionDefinition(FunctionDefinitionAst* node) override;
|
|
void visitAssignment(AssignmentAst* node) override;
|
|
void visitAnnotationAssignment(AnnotationAssignmentAst* node) override;
|
|
+ void visitAssignmentExpression(AssignmentExpressionAst* node) override;
|
|
void visitFor(ForAst* node) override;
|
|
void visitImport(ImportAst* node) override;
|
|
void visitImportFrom(ImportFromAst* node) override;
|
|
diff --git a/duchain/expressionvisitor.cpp b/duchain/expressionvisitor.cpp
|
|
index 5c5286a..055c5b4 100644
|
|
--- a/duchain/expressionvisitor.cpp
|
|
+++ b/duchain/expressionvisitor.cpp
|
|
@@ -757,5 +757,9 @@ void ExpressionVisitor::visitBooleanOperation(Python::BooleanOperationAst* node)
|
|
encounter(result);
|
|
}
|
|
|
|
+void ExpressionVisitor::visitAssignmentExpression(Python::AssignmentExpressionAst* node) {
|
|
+ visitNode(node->value);
|
|
+}
|
|
+
|
|
}
|
|
|
|
diff --git a/duchain/expressionvisitor.h b/duchain/expressionvisitor.h
|
|
index 25ca231..a56481a 100644
|
|
--- a/duchain/expressionvisitor.h
|
|
+++ b/duchain/expressionvisitor.h
|
|
@@ -81,6 +81,7 @@ public:
|
|
void visitSetComprehension(SetComprehensionAst* node) override;
|
|
void visitIfExpression(IfExpressionAst* node) override;
|
|
void visitNameConstant(NameConstantAst* node) override;
|
|
+ void visitAssignmentExpression(AssignmentExpressionAst* node) override;
|
|
|
|
/**
|
|
* @brief Checks for magic docstrings that override a call's return type.
|
|
diff --git a/duchain/tests/pyduchaintest.cpp b/duchain/tests/pyduchaintest.cpp
|
|
index 7142ed2..17ba34e 100644
|
|
--- a/duchain/tests/pyduchaintest.cpp
|
|
+++ b/duchain/tests/pyduchaintest.cpp
|
|
@@ -838,6 +838,7 @@ void PyDUChainTest::testTypes()
|
|
QEXPECT_FAIL("init_class_no_decl", "aliasing info lost", Continue);
|
|
QEXPECT_FAIL("property_wrong", "visitCall uses declaration if no type", Continue);
|
|
QEXPECT_FAIL("property_setter", "very basic property support", Continue);
|
|
+ QEXPECT_FAIL("assignment_expr_context", "not implemented", Continue);
|
|
QCOMPARE(visitor->found, true);
|
|
}
|
|
|
|
@@ -1302,6 +1303,21 @@ void PyDUChainTest::testTypes_data()
|
|
" def foo(self, ccc=aaa, ddd=bbb):\n" // self.bbb is visible here, Foo().aaa isn't.
|
|
" return ccc, ddd\n"
|
|
"checkme = Foo().Bar().foo()\n" << "tuple of (str, int)";
|
|
+#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
|
|
+ QTest::newRow("assignment_expr_while") <<
|
|
+ "file = open('foo.txt')\n"
|
|
+ "while q := file.readline():\n"
|
|
+ " checkme = q\n" << "str";
|
|
+ QTest::newRow("assignment_expr_comprehension") <<
|
|
+ "checkme = [z for q in (1, 2, 3) if (z := q % 2)]" << "list of int";
|
|
+ QTest::newRow("assignment_expr_context") <<
|
|
+ "a = [z for q in (1, 2, 3) if (z := q % 2)]\n"
|
|
+ "checkme = z" << "int";
|
|
+ QTest::newRow("positional_params") <<
|
|
+ "def foo(a, b, /, c, d):\n"
|
|
+ " return a, b, c, d\n"
|
|
+ "checkme = foo(10, 'x', 2.3, d='y')\n" << "tuple of (int, str, float, str)";
|
|
+#endif
|
|
}
|
|
|
|
typedef QPair<Declaration*, int> pair;
|
|
@@ -1780,6 +1796,9 @@ void PyDUChainTest::testVariableCreation_data()
|
|
<< QStringList{"int", "int", "float"};
|
|
QTest::newRow("for_loop_tuple") << "for a in 1, 2: pass" << QStringList{"a"} << QStringList{"int"};
|
|
QTest::newRow("for_loop_dict") << "for a in {'foo': 1}: pass" << QStringList{"a"} << QStringList{"str"};
|
|
+#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
|
|
+ QTest::newRow("assignment_expr") << "a = (b := 10)" << QStringList{"a", "b"} << QStringList{"int", "int"};
|
|
+#endif
|
|
}
|
|
|
|
void PyDUChainTest::testCleanupMultiplePasses()
|
|
diff --git a/parser/ast.cpp b/parser/ast.cpp
|
|
index 9892b18..cd570d3 100644
|
|
--- a/parser/ast.cpp
|
|
+++ b/parser/ast.cpp
|
|
@@ -163,6 +163,11 @@ ExpressionAst::ExpressionAst(Ast* parent, AstType type): Ast(parent, type), valu
|
|
|
|
}
|
|
|
|
+AssignmentExpressionAst::AssignmentExpressionAst(Ast* parent): ExpressionAst(parent, Ast::AssignmentExpressionAstType), value(nullptr)
|
|
+{
|
|
+
|
|
+}
|
|
+
|
|
YieldFromAst::YieldFromAst(Ast* parent) : ExpressionAst(parent, Ast::YieldFromAstType)
|
|
{
|
|
|
|
@@ -248,7 +253,7 @@ NameConstantAst::NameConstantAst(Ast* parent): ExpressionAst(parent, Ast::NameCo
|
|
|
|
}
|
|
|
|
-NumberAst::NumberAst(Ast* parent): ExpressionAst(parent, Ast::NumberAstType), value(0)
|
|
+NumberAst::NumberAst(Ast* parent): ExpressionAst(parent, Ast::NumberAstType), value(0), isInt(false)
|
|
{
|
|
|
|
}
|
|
diff --git a/parser/ast.h b/parser/ast.h
|
|
index 378af0b..65fef1c 100644
|
|
--- a/parser/ast.h
|
|
+++ b/parser/ast.h
|
|
@@ -131,6 +131,7 @@ public:
|
|
SliceAstType,
|
|
EllipsisAstType,
|
|
IndexAstType,
|
|
+ AssignmentExpressionAstType,
|
|
LastExpressionType, // keep this at the end of the expr ast list
|
|
|
|
CodeAstType,
|
|
@@ -457,6 +458,13 @@ public:
|
|
ExpressionAst* value; // WARNING this is not set in most cases!
|
|
};
|
|
|
|
+class KDEVPYTHONPARSER_EXPORT AssignmentExpressionAst : public ExpressionAst {
|
|
+public:
|
|
+ AssignmentExpressionAst(Ast* parent);
|
|
+ ExpressionAst* target;
|
|
+ ExpressionAst* value;
|
|
+};
|
|
+
|
|
class KDEVPYTHONPARSER_EXPORT AwaitAst : public ExpressionAst {
|
|
public:
|
|
AwaitAst(Ast* parent);
|
|
@@ -743,6 +751,7 @@ public:
|
|
ArgumentsAst(Ast* parent);
|
|
QList<ArgAst*> arguments;
|
|
QList<ArgAst*> kwonlyargs;
|
|
+ QList<ArgAst*> posonlyargs;
|
|
QList<ExpressionAst*> defaultValues;
|
|
ArgAst* vararg;
|
|
ArgAst* kwarg;
|
|
diff --git a/parser/astbuilder.cpp b/parser/astbuilder.cpp
|
|
index a1ccd68..ad2e0dc 100644
|
|
--- a/parser/astbuilder.cpp
|
|
+++ b/parser/astbuilder.cpp
|
|
@@ -101,7 +101,13 @@ CodeAst::Ptr AstBuilder::parse(const QUrl& filename, QString &contents)
|
|
PythonInitializer pyIniter(pyInitLock);
|
|
PyArena* arena = pyIniter.arena;
|
|
|
|
+#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
|
|
+ PyCompilerFlags flags;
|
|
+ flags.cf_flags = PyCF_SOURCE_IS_UTF8 | PyCF_IGNORE_COOKIE | PyCF_ONLY_AST;
|
|
+ flags.cf_feature_version = 7;
|
|
+#else
|
|
PyCompilerFlags flags = {PyCF_SOURCE_IS_UTF8 | PyCF_IGNORE_COOKIE};
|
|
+#endif
|
|
|
|
CythonSyntaxRemover cythonSyntaxRemover;
|
|
|
|
diff --git a/parser/astdefaultvisitor.cpp b/parser/astdefaultvisitor.cpp
|
|
index 5db1f6f..cdd31bb 100644
|
|
--- a/parser/astdefaultvisitor.cpp
|
|
+++ b/parser/astdefaultvisitor.cpp
|
|
@@ -292,6 +292,12 @@ void AstDefaultVisitor::visitAnnotationAssignment(AnnotationAssignmentAst* node)
|
|
visitNode(node->value);
|
|
}
|
|
|
|
+void AstDefaultVisitor::visitAssignmentExpression(AssignmentExpressionAst* node)
|
|
+{
|
|
+ visitNode(node->target);
|
|
+ visitNode(node->value);
|
|
+}
|
|
+
|
|
void AstDefaultVisitor::visitBinaryOperation(BinaryOperationAst* node)
|
|
{
|
|
visitNode(node->lhs);
|
|
diff --git a/parser/astdefaultvisitor.h b/parser/astdefaultvisitor.h
|
|
index e8e0d3d..aa1f540 100644
|
|
--- a/parser/astdefaultvisitor.h
|
|
+++ b/parser/astdefaultvisitor.h
|
|
@@ -49,6 +49,7 @@ public:
|
|
void visitAssignment(AssignmentAst* node) override;
|
|
void visitAugmentedAssignment(AugmentedAssignmentAst* node) override;
|
|
void visitAnnotationAssignment(AnnotationAssignmentAst* node) override;
|
|
+ void visitAssignmentExpression(AssignmentExpressionAst* node) override;
|
|
void visitFor(ForAst* node) override;
|
|
void visitWhile(WhileAst* node) override;
|
|
void visitIf(IfAst* node) override;
|
|
@@ -122,6 +123,7 @@ public:
|
|
void visitAssignment(AssignmentAst* node) override { AstDefaultVisitor::visitAssignment(node); delete node; }
|
|
void visitAugmentedAssignment(AugmentedAssignmentAst* node) override { AstDefaultVisitor::visitAugmentedAssignment(node); delete node; }
|
|
void visitAnnotationAssignment(AnnotationAssignmentAst* node) override { AstDefaultVisitor::visitAnnotationAssignment(node); delete node; }
|
|
+ void visitAssignmentExpression(AssignmentExpressionAst* node) override { AstDefaultVisitor::visitAssignmentExpression(node); delete node; }
|
|
void visitFor(ForAst* node) override { AstDefaultVisitor::visitFor(node); delete node; }
|
|
void visitWhile(WhileAst* node) override { AstDefaultVisitor::visitWhile(node); delete node; }
|
|
void visitIf(IfAst* node) override { AstDefaultVisitor::visitIf(node); delete node; }
|
|
diff --git a/parser/astvisitor.cpp b/parser/astvisitor.cpp
|
|
index ace7d61..51c5a1c 100644
|
|
--- a/parser/astvisitor.cpp
|
|
+++ b/parser/astvisitor.cpp
|
|
@@ -47,6 +47,7 @@ void AstVisitor::visitNode(Ast* node)
|
|
case Ast::AssignmentAstType: this->visitAssignment(static_cast<AssignmentAst*>(node)); break;
|
|
case Ast::AugmentedAssignmentAstType: this->visitAugmentedAssignment(static_cast<AugmentedAssignmentAst*>(node)); break;
|
|
case Ast::AnnotationAssignmentAstType: this->visitAnnotationAssignment(static_cast<AnnotationAssignmentAst*>(node)); break;
|
|
+ case Ast::AssignmentExpressionAstType: this->visitAssignmentExpression(static_cast<AssignmentExpressionAst*>(node)); break;
|
|
case Ast::ForAstType: this->visitFor(static_cast<ForAst*>(node)); break;
|
|
case Ast::WhileAstType: this->visitWhile(static_cast<WhileAst*>(node)); break;
|
|
case Ast::IfAstType: this->visitIf(static_cast<IfAst*>(node)); break;
|
|
diff --git a/parser/astvisitor.h b/parser/astvisitor.h
|
|
index 1908e9d..51aa47b 100644
|
|
--- a/parser/astvisitor.h
|
|
+++ b/parser/astvisitor.h
|
|
@@ -61,6 +61,7 @@ public:
|
|
virtual void visitAssignment(AssignmentAst* node) { Q_UNUSED(node); };
|
|
virtual void visitAugmentedAssignment(AugmentedAssignmentAst* node) { Q_UNUSED(node); };
|
|
virtual void visitAnnotationAssignment(AnnotationAssignmentAst* node) { Q_UNUSED(node); };
|
|
+ virtual void visitAssignmentExpression(AssignmentExpressionAst* node) { Q_UNUSED(node); };
|
|
virtual void visitFor(ForAst* node) { Q_UNUSED(node); };
|
|
virtual void visitWhile(WhileAst* node) { Q_UNUSED(node); };
|
|
virtual void visitIf(IfAst* node) { Q_UNUSED(node); };
|
|
diff --git a/parser/conversionGenerator.py b/parser/conversionGenerator.py
|
|
index 9d65cc0..6605595 100644
|
|
--- a/parser/conversionGenerator.py
|
|
+++ b/parser/conversionGenerator.py
|
|
@@ -9,7 +9,7 @@
|
|
|
|
import sys
|
|
|
|
-contents = open('python36.sdef').read().replace("\n", "").split(';;')
|
|
+contents = open('python38.sdef').read().replace("\n", "").split(';;')
|
|
|
|
func_structure = '''
|
|
Ast* visitNode(%{RULE_FOR}* node) {
|
|
@@ -45,7 +45,6 @@ simple_func_structure = '''
|
|
|
|
switch_line = ''' case %{KIND}: {
|
|
%{ACTIONS}
|
|
- result = v;
|
|
break;
|
|
}'''
|
|
|
|
@@ -139,6 +138,7 @@ for rule in contents:
|
|
results[rule_for] = list()
|
|
|
|
current_actions = list()
|
|
+ created_v = False
|
|
for action in actions:
|
|
command = action.split('|')[0]
|
|
try:
|
|
@@ -204,14 +204,17 @@ for rule in contents:
|
|
elif command == 'create':
|
|
astType = arguments
|
|
current_actions.append(create_ast_line.replace('%{AST_TYPE}', astType))
|
|
-
|
|
+ created_v = True
|
|
+
|
|
if code:
|
|
current_actions.append(code);
|
|
-
|
|
+
|
|
current_actions = "\n".join(current_actions)
|
|
if kind == 'any':
|
|
current_stmt = current_actions
|
|
else:
|
|
+ if created_v:
|
|
+ current_actions += "\n result = v;"
|
|
current_stmt = switch_line.replace('%{KIND}', kind).replace('%{ACTIONS}', current_actions)
|
|
if before_version:
|
|
version_cpp_if = ("#if PYTHON_VERSION < QT_VERSION_CHECK(%d, %d, 0)\n"
|
|
diff --git a/parser/generated.h b/parser/generated.h
|
|
index 9061deb..e1136f8 100644
|
|
--- a/parser/generated.h
|
|
+++ b/parser/generated.h
|
|
@@ -76,12 +76,23 @@ private:
|
|
Ast* visitNode(_arguments* node) {
|
|
bool ranges_copied = false; Q_UNUSED(ranges_copied);
|
|
if ( ! node ) return nullptr;
|
|
+#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
|
|
ArgumentsAst* v = new ArgumentsAst(parent());
|
|
nodeStack.push(v); v->vararg = static_cast<ArgAst*>(visitNode(node->vararg)); nodeStack.pop();
|
|
nodeStack.push(v); v->kwarg = static_cast<ArgAst*>(visitNode(node->kwarg)); nodeStack.pop();
|
|
nodeStack.push(v); v->arguments = visitNodeList<_arg, ArgAst>(node->args); nodeStack.pop();
|
|
nodeStack.push(v); v->defaultValues = visitNodeList<_expr, ExpressionAst>(node->defaults); nodeStack.pop();
|
|
nodeStack.push(v); v->kwonlyargs = visitNodeList<_arg, ArgAst>(node->kwonlyargs); nodeStack.pop();
|
|
+#endif
|
|
+#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
|
|
+ ArgumentsAst* v = new ArgumentsAst(parent());
|
|
+ nodeStack.push(v); v->vararg = static_cast<ArgAst*>(visitNode(node->vararg)); nodeStack.pop();
|
|
+ nodeStack.push(v); v->kwarg = static_cast<ArgAst*>(visitNode(node->kwarg)); nodeStack.pop();
|
|
+ nodeStack.push(v); v->arguments = visitNodeList<_arg, ArgAst>(node->args); nodeStack.pop();
|
|
+ nodeStack.push(v); v->defaultValues = visitNodeList<_expr, ExpressionAst>(node->defaults); nodeStack.pop();
|
|
+ nodeStack.push(v); v->kwonlyargs = visitNodeList<_arg, ArgAst>(node->kwonlyargs); nodeStack.pop();
|
|
+ nodeStack.push(v); v->posonlyargs = visitNodeList<_arg, ArgAst>(node->posonlyargs); nodeStack.pop();
|
|
+#endif
|
|
return v;
|
|
}
|
|
|
|
@@ -280,18 +291,22 @@ private:
|
|
break;
|
|
}
|
|
#endif
|
|
+#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
|
|
case Num_kind: {
|
|
NumberAst* v = new NumberAst(parent());
|
|
v->isInt = PyLong_Check(node->v.Num.n); v->value = PyLong_AsLong(node->v.Num.n);
|
|
result = v;
|
|
break;
|
|
}
|
|
+#endif
|
|
+#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
|
|
case Str_kind: {
|
|
StringAst* v = new StringAst(parent());
|
|
v->value = PyUnicodeObjectToQString(node->v.Str.s);
|
|
result = v;
|
|
break;
|
|
}
|
|
+#endif
|
|
#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0)
|
|
case JoinedStr_kind: {
|
|
JoinedStringAst* v = new JoinedStringAst(parent());
|
|
@@ -310,12 +325,14 @@ private:
|
|
break;
|
|
}
|
|
#endif
|
|
+#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
|
|
case Bytes_kind: {
|
|
BytesAst* v = new BytesAst(parent());
|
|
v->value = PyUnicodeObjectToQString(node->v.Bytes.s);
|
|
result = v;
|
|
break;
|
|
}
|
|
+#endif
|
|
case Attribute_kind: {
|
|
AttributeAst* v = new AttributeAst(parent());
|
|
v->attribute = node->v.Attribute.attr ? new Python::Identifier(PyUnicodeObjectToQString(node->v.Attribute.attr)) : nullptr;
|
|
@@ -374,23 +391,42 @@ private:
|
|
result = v;
|
|
break;
|
|
}
|
|
+#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
|
|
case Ellipsis_kind: {
|
|
EllipsisAst* v = new EllipsisAst(parent());
|
|
result = v;
|
|
break;
|
|
}
|
|
+#endif
|
|
+#if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0)
|
|
case NameConstant_kind: {
|
|
NameConstantAst* v = new NameConstantAst(parent());
|
|
v->value = node->v.NameConstant.value == Py_None ? NameConstantAst::None : node->v.NameConstant.value == Py_False ? NameConstantAst::False : NameConstantAst::True;
|
|
result = v;
|
|
break;
|
|
}
|
|
+#endif
|
|
case YieldFrom_kind: {
|
|
YieldFromAst* v = new YieldFromAst(parent());
|
|
nodeStack.push(v); v->value = static_cast<ExpressionAst*>(visitNode(node->v.YieldFrom.value)); nodeStack.pop();
|
|
result = v;
|
|
break;
|
|
}
|
|
+#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
|
|
+ case Constant_kind: {
|
|
+PyObject *value = node->v.Constant.value;if (value == Py_None) { NameConstantAst* v = new NameConstantAst(parent()); v->value = NameConstantAst::None; result = v;}else if (value == Py_True) { NameConstantAst* v = new NameConstantAst(parent()); v->value = NameConstantAst::True; result = v;}else if (value == Py_False) { NameConstantAst* v = new NameConstantAst(parent()); v->value = NameConstantAst::False; result = v;}else if (value->ob_type == &PyLong_Type) { NumberAst* v = new NumberAst(parent()); v->isInt = true; v->value = PyLong_AsLong(value); result = v;}else if (value->ob_type == &PyFloat_Type || value->ob_type == &PyComplex_Type) { result = new NumberAst(parent());}else if (value->ob_type == &PyUnicode_Type) { StringAst* v = new StringAst(parent()); v->value = PyUnicodeObjectToQString(value); result = v;}else if (value->ob_type == &PyBytes_Type) { result = new BytesAst(parent());}else if (value->ob_type == &PyEllipsis_Type) { result = new EllipsisAst(parent());}else { qWarning() << "Unhandled constant type: " << value->ob_type->tp_name; Q_ASSERT(false);};
|
|
+ break;
|
|
+ }
|
|
+#endif
|
|
+#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
|
|
+ case NamedExpr_kind: {
|
|
+ AssignmentExpressionAst* v = new AssignmentExpressionAst(parent());
|
|
+ nodeStack.push(v); v->target = static_cast<ExpressionAst*>(visitNode(node->v.NamedExpr.target)); nodeStack.pop();
|
|
+ nodeStack.push(v); v->value = static_cast<ExpressionAst*>(visitNode(node->v.NamedExpr.value)); nodeStack.pop();
|
|
+ result = v;
|
|
+ break;
|
|
+ }
|
|
+#endif
|
|
default:
|
|
qWarning() << "Unsupported _expr AST type: " << node->kind;
|
|
Q_ASSERT(false);
|
|
diff --git a/parser/python36.sdef b/parser/python36.sdef
|
|
deleted file mode 100644
|
|
index f53ff1c..0000000
|
|
--- a/parser/python36.sdef
|
|
+++ /dev/null
|
|
@@ -1,102 +0,0 @@
|
|
-COMMENT;This file specifies rules for a conversion of a python (C) to a plugin-internal (C++) syntax tree;;
|
|
-COMMENT;All lines are terminated by a double semicolon token, newlines are ignored.;;
|
|
-COMMENT;-> stands for "convert AST", => for "convert AST list", ~> for "make an identifier", :> is an assignment w/o conversion, and *> is an enum cast.;;
|
|
-COMMENT;$> is a string assignment, +> is a "mindless assignment, like, it just does v->arg = node->arg.
|
|
-COMMENT;_> is a Singleton Assignment (converts Py_True, Py_False, Py_None to enum)
|
|
-COMMENT;the CODE statement can be used to add custom code.;;
|
|
-
|
|
-
|
|
-RULE_FOR _stmt;KIND Expr_kind;ACTIONS create|ExpressionAst set|value->ExpressionAst,value;;
|
|
-RULE_FOR _stmt;KIND FunctionDef_kind;ACTIONS create|FunctionDefinitionAst set|name~>name set|arguments->ArgumentsAst,args
|
|
- set|body=>Ast,body set|decorators=>ExpressionAst,decorator_list set|returns->ExpressionAst,returns;;
|
|
-RULE_FOR _stmt;KIND AsyncFunctionDef_kind;ACTIONS create|FunctionDefinitionAst set|name~>name set|arguments->ArgumentsAst,args
|
|
- set|body=>Ast,body set|decorators=>ExpressionAst,decorator_list set|returns->ExpressionAst,returns;SINCE 3.5;CODE v->async = true;;
|
|
-RULE_FOR _stmt;KIND ClassDef_kind;ACTIONS create|ClassDefinitionAst set|name~>name set|baseClasses=>ExpressionAst,bases set|body=>Ast,body
|
|
- set|decorators=>ExpressionAst,decorator_list;;
|
|
-RULE_FOR _stmt;KIND Return_kind;ACTIONS create|ReturnAst set|value->ExpressionAst,value;;
|
|
-RULE_FOR _stmt;KIND Delete_kind;ACTIONS create|DeleteAst set|targets=>ExpressionAst,targets;;
|
|
-RULE_FOR _stmt;KIND Assign_kind;ACTIONS create|AssignmentAst set|targets=>ExpressionAst,targets set|value->ExpressionAst,value;;
|
|
-RULE_FOR _stmt;KIND AugAssign_kind;ACTIONS create|AugmentedAssignmentAst set|target->ExpressionAst,target set|op*>OperatorTypes,op set|value->ExpressionAst,value;;
|
|
-RULE_FOR _stmt;KIND AnnAssign_kind;ACTIONS create|AnnotationAssignmentAst set|target->ExpressionAst,target set|annotation->ExpressionAst,annotation set|value->ExpressionAst,value;SINCE 3.6;;
|
|
-RULE_FOR _stmt;KIND For_kind;ACTIONS create|ForAst set|target->ExpressionAst,target set|iterator->ExpressionAst,iter set|body=>Ast,body set|orelse=>Ast,orelse;;
|
|
-RULE_FOR _stmt;KIND AsyncFor_kind;ACTIONS create|ForAst set|target->ExpressionAst,target set|iterator->ExpressionAst,iter set|body=>Ast,body set|orelse=>Ast,orelse;SINCE 3.5;;
|
|
-RULE_FOR _stmt;KIND While_kind;ACTIONS create|WhileAst set|condition->ExpressionAst,test set|body=>Ast,body set|orelse=>Ast,orelse;;
|
|
-RULE_FOR _stmt;KIND If_kind;ACTIONS create|IfAst set|condition->ExpressionAst,test set|body=>Ast,body set|orelse=>Ast,orelse;;
|
|
-RULE_FOR _stmt;KIND With_kind;ACTIONS create|WithAst set|body=>Ast,body set|items=>WithItemAst,items;;
|
|
-RULE_FOR _stmt;KIND AsyncWith_kind;ACTIONS create|WithAst set|body=>Ast,body set|items=>WithItemAst,items;SINCE 3.5;;
|
|
-
|
|
-COMMENT;FIXME: the struct Raise has changed, so the following line is likely wrong;;
|
|
-RULE_FOR _stmt;KIND Raise_kind;ACTIONS create|RaiseAst set|type->ExpressionAst,exc;;
|
|
-RULE_FOR _stmt;KIND Try_kind;ACTIONS create|TryAst set|body=>Ast,body set|handlers=>ExceptionHandlerAst,handlers set|orelse=>Ast,orelse set|finally=>Ast,finalbody;;
|
|
-RULE_FOR _stmt;KIND Assert_kind;ACTIONS create|AssertionAst set|condition->ExpressionAst,test set|message->ExpressionAst,msg;;
|
|
-RULE_FOR _stmt;KIND Import_kind;ACTIONS create|ImportAst set|names=>AliasAst,names;;
|
|
-RULE_FOR _stmt;KIND ImportFrom_kind;ACTIONS create|ImportFromAst set|module~>module set|names=>AliasAst,names set|level:>level;;
|
|
-RULE_FOR _stmt;KIND Global_kind;ACTIONS create|GlobalAst set|names=>Identifier,names;;
|
|
-RULE_FOR _stmt;KIND Break_kind;ACTIONS create|BreakAst;;
|
|
-RULE_FOR _stmt;KIND Continue_kind;ACTIONS create|ContinueAst;;
|
|
-RULE_FOR _stmt;KIND Pass_kind;ACTIONS create|PassAst;;
|
|
-RULE_FOR _stmt;KIND Nonlocal_kind;ACTIONS create|NonlocalAst;;
|
|
-
|
|
-RULE_FOR _expr;KIND Await_kind;ACTIONS create|AwaitAst set|value->ExpressionAst,value;SINCE 3.5;;
|
|
-RULE_FOR _expr;KIND BoolOp_kind;ACTIONS create|BooleanOperationAst set|type*>BooleanOperationTypes,op set|values=>ExpressionAst,values;;
|
|
-RULE_FOR _expr;KIND BinOp_kind;ACTIONS create|BinaryOperationAst set|type*>OperatorTypes,op set|lhs->ExpressionAst,left set|rhs->ExpressionAst,right;;
|
|
-RULE_FOR _expr;KIND UnaryOp_kind;ACTIONS create|UnaryOperationAst set|type*>UnaryOperatorTypes,op set|operand->ExpressionAst,operand;;
|
|
-RULE_FOR _expr;KIND Lambda_kind;ACTIONS create|LambdaAst set|arguments->ArgumentsAst,args set|body->ExpressionAst,body;;
|
|
-RULE_FOR _expr;KIND IfExp_kind;ACTIONS create|IfExpressionAst set|condition->ExpressionAst,test set|body->ExpressionAst,body set|orelse->ExpressionAst,orelse;;
|
|
-RULE_FOR _expr;KIND Dict_kind;ACTIONS create|DictAst set|keys=>ExpressionAst,keys set|values=>ExpressionAst,values;;
|
|
-RULE_FOR _expr;KIND Set_kind;ACTIONS create|SetAst set|elements=>ExpressionAst,elts;;
|
|
-RULE_FOR _expr;KIND ListComp_kind;ACTIONS create|ListComprehensionAst set|element->ExpressionAst,elt set|generators=>ComprehensionAst,generators;;
|
|
-RULE_FOR _expr;KIND SetComp_kind;ACTIONS create|SetComprehensionAst set|element->ExpressionAst,elt set|generators=>ComprehensionAst,generators;;
|
|
-RULE_FOR _expr;KIND DictComp_kind;ACTIONS create|DictionaryComprehensionAst set|key->ExpressionAst,key set|value->ExpressionAst,value set|generators=>ComprehensionAst,generators;;
|
|
-RULE_FOR _expr;KIND GeneratorExp_kind;ACTIONS create|GeneratorExpressionAst set|element->ExpressionAst,elt set|generators=>ComprehensionAst,generators;;
|
|
-RULE_FOR _expr;KIND Yield_kind;ACTIONS create|YieldAst set|value->ExpressionAst,value;;
|
|
-RULE_FOR _expr;KIND Compare_kind;ACTIONS create|CompareAst set|leftmostElement->ExpressionAst,left set|operators#>ComparisonOperatorTypes,ops set|comparands=>ExpressionAst,comparators;;
|
|
-RULE_FOR _expr;KIND Call_kind;ACTIONS create|CallAst set|function->ExpressionAst,func set|arguments=>ExpressionAst,args set|keywords=>KeywordAst,keywords;SINCE 3.5;;
|
|
-RULE_FOR _expr;KIND Call_kind;ACTIONS create|CallAst set|function->ExpressionAst,func set|arguments=>ExpressionAst,args set|keywords=>KeywordAst,keywords;BEFORE 3.5;
|
|
-CODE /* Convert 3.4 unpacked-args AST to match the new format from 3.5+ */
|
|
-if (node->v.Call.starargs) {
|
|
- nodeStack.push(v);
|
|
- auto starred = new StarredAst(v);
|
|
- starred->context = ExpressionAst::Context::Load;
|
|
- nodeStack.push(starred);
|
|
- starred->value = static_cast<ExpressionAst*>(visitNode(node->v.Call.starargs));
|
|
- nodeStack.pop();
|
|
- v->arguments.append(starred);
|
|
- nodeStack.pop();
|
|
-};
|
|
-if (node->v.Call.kwargs) {
|
|
- nodeStack.push(v);
|
|
- auto kwargs = new KeywordAst(v);
|
|
- nodeStack.push(kwargs);
|
|
- kwargs->value = static_cast<ExpressionAst*>(visitNode(node->v.Call.kwargs));
|
|
- nodeStack.pop();
|
|
- v->keywords.append(kwargs);
|
|
- nodeStack.pop();
|
|
-};;
|
|
-RULE_FOR _expr;KIND Num_kind;ACTIONS create|NumberAst;CODE v->isInt = PyLong_Check(node->v.Num.n); v->value = PyLong_AsLong(node->v.Num.n);;
|
|
-RULE_FOR _expr;KIND Str_kind;ACTIONS create|StringAst set|value$>s;;
|
|
-RULE_FOR _expr;KIND JoinedStr_kind;ACTIONS create|JoinedStringAst set|values=>ExpressionAst,values;SINCE 3.6;;
|
|
-RULE_FOR _expr;KIND FormattedValue_kind;ACTIONS create|FormattedValueAst set|value->ExpressionAst,value set|conversion:>conversion set|formatSpec->ExpressionAst,format_spec;SINCE 3.6;;
|
|
-RULE_FOR _expr;KIND Bytes_kind;ACTIONS create|BytesAst set|value$>s;;
|
|
-RULE_FOR _expr;KIND Attribute_kind;ACTIONS create|AttributeAst set|attribute~>attr set|value->ExpressionAst,value set|context*>Context,ctx;;
|
|
-RULE_FOR _expr;KIND Subscript_kind;ACTIONS create|SubscriptAst set|value->ExpressionAst,value set|slice->SliceAst,slice set|context*>Context,ctx;;
|
|
-RULE_FOR _expr;KIND Starred_kind;ACTIONS create|StarredAst set|value->ExpressionAst,value set|context*>Context,ctx;;
|
|
-RULE_FOR _expr;KIND Name_kind;ACTIONS create|NameAst set|identifier~>id set|context*>Context,ctx;;
|
|
-RULE_FOR _expr;KIND List_kind;ACTIONS create|ListAst set|elements=>ExpressionAst,elts set|context*>Context,ctx;;
|
|
-RULE_FOR _expr;KIND Tuple_kind;ACTIONS create|TupleAst set|elements=>ExpressionAst,elts set|context*>Context,ctx;;
|
|
-RULE_FOR _expr;KIND Ellipsis_kind;ACTIONS create|EllipsisAst;;
|
|
-RULE_FOR _expr;KIND NameConstant_kind;ACTIONS create|NameConstantAst set|value_>value;;
|
|
-RULE_FOR _expr;KIND YieldFrom_kind;ACTIONS create|YieldFromAst set|value->ExpressionAst,value;;
|
|
-
|
|
-RULE_FOR _slice;KIND Slice_kind;ACTIONS create|SliceAst set|lower->ExpressionAst,lower set|upper->ExpressionAst,upper set|step->ExpressionAst,step;;
|
|
-RULE_FOR _slice;KIND ExtSlice_kind;ACTIONS create|ExtendedSliceAst set|dims=>SliceAst,dims;;
|
|
-RULE_FOR _slice;KIND Index_kind;ACTIONS create|IndexAst set|value->ExpressionAst,value;;
|
|
-
|
|
-
|
|
-RULE_FOR _comprehension;KIND any;ACTIONS create|ComprehensionAst set|target->ExpressionAst,target set|iterator->ExpressionAst,iter set|conditions=>ExpressionAst,ifs;;
|
|
-RULE_FOR _excepthandler;KIND ExceptHandler_kind;ACTIONS create|ExceptionHandlerAst set|type->ExpressionAst,type set|name~>name set|body=>Ast,body;;
|
|
-RULE_FOR _arguments;KIND any;ACTIONS create|ArgumentsAst set|vararg->ArgAst,vararg set|kwarg->ArgAst,kwarg set|arguments=>ArgAst,args set|defaultValues=>ExpressionAst,defaults set|kwonlyargs=>ArgAst,kwonlyargs;;
|
|
-RULE_FOR _arg;KIND any;ACTIONS create|ArgAst set|argumentName~>arg set|annotation->ExpressionAst,annotation;;
|
|
-RULE_FOR _keyword;KIND any;ACTIONS create|KeywordAst set|argumentName~>arg set|value->ExpressionAst,value;;
|
|
-RULE_FOR _alias;KIND any;ACTIONS create|AliasAst set|name~>name set|asName~>asname;;
|
|
-RULE_FOR _withitem;KIND any; ACTIONS create|WithItemAst set|contextExpression->ExpressionAst,context_expr set|optionalVars->ExpressionAst,optional_vars;;
|
|
diff --git a/parser/python38.sdef b/parser/python38.sdef
|
|
new file mode 100644
|
|
index 0000000..30d9f95
|
|
--- /dev/null
|
|
+++ b/parser/python38.sdef
|
|
@@ -0,0 +1,145 @@
|
|
+COMMENT;This file specifies rules for a conversion of a python (C) to a plugin-internal (C++) syntax tree;;
|
|
+COMMENT;All lines are terminated by a double semicolon token, newlines are ignored.;;
|
|
+COMMENT;-> stands for "convert AST", => for "convert AST list", ~> for "make an identifier", :> is an assignment w/o conversion, and *> is an enum cast.;;
|
|
+COMMENT;$> is a string assignment, +> is a "mindless assignment, like, it just does v->arg = node->arg.
|
|
+COMMENT;_> is a Singleton Assignment (converts Py_True, Py_False, Py_None to enum)
|
|
+COMMENT;the CODE statement can be used to add custom code.;;
|
|
+
|
|
+
|
|
+RULE_FOR _stmt;KIND Expr_kind;ACTIONS create|ExpressionAst set|value->ExpressionAst,value;;
|
|
+RULE_FOR _stmt;KIND FunctionDef_kind;ACTIONS create|FunctionDefinitionAst set|name~>name set|arguments->ArgumentsAst,args
|
|
+ set|body=>Ast,body set|decorators=>ExpressionAst,decorator_list set|returns->ExpressionAst,returns;;
|
|
+RULE_FOR _stmt;KIND AsyncFunctionDef_kind;ACTIONS create|FunctionDefinitionAst set|name~>name set|arguments->ArgumentsAst,args
|
|
+ set|body=>Ast,body set|decorators=>ExpressionAst,decorator_list set|returns->ExpressionAst,returns;SINCE 3.5;CODE v->async = true;;
|
|
+RULE_FOR _stmt;KIND ClassDef_kind;ACTIONS create|ClassDefinitionAst set|name~>name set|baseClasses=>ExpressionAst,bases set|body=>Ast,body
|
|
+ set|decorators=>ExpressionAst,decorator_list;;
|
|
+RULE_FOR _stmt;KIND Return_kind;ACTIONS create|ReturnAst set|value->ExpressionAst,value;;
|
|
+RULE_FOR _stmt;KIND Delete_kind;ACTIONS create|DeleteAst set|targets=>ExpressionAst,targets;;
|
|
+RULE_FOR _stmt;KIND Assign_kind;ACTIONS create|AssignmentAst set|targets=>ExpressionAst,targets set|value->ExpressionAst,value;;
|
|
+RULE_FOR _stmt;KIND AugAssign_kind;ACTIONS create|AugmentedAssignmentAst set|target->ExpressionAst,target set|op*>OperatorTypes,op set|value->ExpressionAst,value;;
|
|
+RULE_FOR _stmt;KIND AnnAssign_kind;ACTIONS create|AnnotationAssignmentAst set|target->ExpressionAst,target set|annotation->ExpressionAst,annotation set|value->ExpressionAst,value;SINCE 3.6;;
|
|
+RULE_FOR _stmt;KIND For_kind;ACTIONS create|ForAst set|target->ExpressionAst,target set|iterator->ExpressionAst,iter set|body=>Ast,body set|orelse=>Ast,orelse;;
|
|
+RULE_FOR _stmt;KIND AsyncFor_kind;ACTIONS create|ForAst set|target->ExpressionAst,target set|iterator->ExpressionAst,iter set|body=>Ast,body set|orelse=>Ast,orelse;SINCE 3.5;;
|
|
+RULE_FOR _stmt;KIND While_kind;ACTIONS create|WhileAst set|condition->ExpressionAst,test set|body=>Ast,body set|orelse=>Ast,orelse;;
|
|
+RULE_FOR _stmt;KIND If_kind;ACTIONS create|IfAst set|condition->ExpressionAst,test set|body=>Ast,body set|orelse=>Ast,orelse;;
|
|
+RULE_FOR _stmt;KIND With_kind;ACTIONS create|WithAst set|body=>Ast,body set|items=>WithItemAst,items;;
|
|
+RULE_FOR _stmt;KIND AsyncWith_kind;ACTIONS create|WithAst set|body=>Ast,body set|items=>WithItemAst,items;SINCE 3.5;;
|
|
+
|
|
+COMMENT;FIXME: the struct Raise has changed, so the following line is likely wrong;;
|
|
+RULE_FOR _stmt;KIND Raise_kind;ACTIONS create|RaiseAst set|type->ExpressionAst,exc;;
|
|
+RULE_FOR _stmt;KIND Try_kind;ACTIONS create|TryAst set|body=>Ast,body set|handlers=>ExceptionHandlerAst,handlers set|orelse=>Ast,orelse set|finally=>Ast,finalbody;;
|
|
+RULE_FOR _stmt;KIND Assert_kind;ACTIONS create|AssertionAst set|condition->ExpressionAst,test set|message->ExpressionAst,msg;;
|
|
+RULE_FOR _stmt;KIND Import_kind;ACTIONS create|ImportAst set|names=>AliasAst,names;;
|
|
+RULE_FOR _stmt;KIND ImportFrom_kind;ACTIONS create|ImportFromAst set|module~>module set|names=>AliasAst,names set|level:>level;;
|
|
+RULE_FOR _stmt;KIND Global_kind;ACTIONS create|GlobalAst set|names=>Identifier,names;;
|
|
+RULE_FOR _stmt;KIND Break_kind;ACTIONS create|BreakAst;;
|
|
+RULE_FOR _stmt;KIND Continue_kind;ACTIONS create|ContinueAst;;
|
|
+RULE_FOR _stmt;KIND Pass_kind;ACTIONS create|PassAst;;
|
|
+RULE_FOR _stmt;KIND Nonlocal_kind;ACTIONS create|NonlocalAst;;
|
|
+
|
|
+RULE_FOR _expr;KIND Await_kind;ACTIONS create|AwaitAst set|value->ExpressionAst,value;SINCE 3.5;;
|
|
+RULE_FOR _expr;KIND BoolOp_kind;ACTIONS create|BooleanOperationAst set|type*>BooleanOperationTypes,op set|values=>ExpressionAst,values;;
|
|
+RULE_FOR _expr;KIND BinOp_kind;ACTIONS create|BinaryOperationAst set|type*>OperatorTypes,op set|lhs->ExpressionAst,left set|rhs->ExpressionAst,right;;
|
|
+RULE_FOR _expr;KIND UnaryOp_kind;ACTIONS create|UnaryOperationAst set|type*>UnaryOperatorTypes,op set|operand->ExpressionAst,operand;;
|
|
+RULE_FOR _expr;KIND Lambda_kind;ACTIONS create|LambdaAst set|arguments->ArgumentsAst,args set|body->ExpressionAst,body;;
|
|
+RULE_FOR _expr;KIND IfExp_kind;ACTIONS create|IfExpressionAst set|condition->ExpressionAst,test set|body->ExpressionAst,body set|orelse->ExpressionAst,orelse;;
|
|
+RULE_FOR _expr;KIND Dict_kind;ACTIONS create|DictAst set|keys=>ExpressionAst,keys set|values=>ExpressionAst,values;;
|
|
+RULE_FOR _expr;KIND Set_kind;ACTIONS create|SetAst set|elements=>ExpressionAst,elts;;
|
|
+RULE_FOR _expr;KIND ListComp_kind;ACTIONS create|ListComprehensionAst set|element->ExpressionAst,elt set|generators=>ComprehensionAst,generators;;
|
|
+RULE_FOR _expr;KIND SetComp_kind;ACTIONS create|SetComprehensionAst set|element->ExpressionAst,elt set|generators=>ComprehensionAst,generators;;
|
|
+RULE_FOR _expr;KIND DictComp_kind;ACTIONS create|DictionaryComprehensionAst set|key->ExpressionAst,key set|value->ExpressionAst,value set|generators=>ComprehensionAst,generators;;
|
|
+RULE_FOR _expr;KIND GeneratorExp_kind;ACTIONS create|GeneratorExpressionAst set|element->ExpressionAst,elt set|generators=>ComprehensionAst,generators;;
|
|
+RULE_FOR _expr;KIND Yield_kind;ACTIONS create|YieldAst set|value->ExpressionAst,value;;
|
|
+RULE_FOR _expr;KIND Compare_kind;ACTIONS create|CompareAst set|leftmostElement->ExpressionAst,left set|operators#>ComparisonOperatorTypes,ops set|comparands=>ExpressionAst,comparators;;
|
|
+RULE_FOR _expr;KIND Call_kind;ACTIONS create|CallAst set|function->ExpressionAst,func set|arguments=>ExpressionAst,args set|keywords=>KeywordAst,keywords;SINCE 3.5;;
|
|
+RULE_FOR _expr;KIND Call_kind;ACTIONS create|CallAst set|function->ExpressionAst,func set|arguments=>ExpressionAst,args set|keywords=>KeywordAst,keywords;BEFORE 3.5;
|
|
+CODE /* Convert 3.4 unpacked-args AST to match the new format from 3.5+ */
|
|
+if (node->v.Call.starargs) {
|
|
+ nodeStack.push(v);
|
|
+ auto starred = new StarredAst(v);
|
|
+ starred->context = ExpressionAst::Context::Load;
|
|
+ nodeStack.push(starred);
|
|
+ starred->value = static_cast<ExpressionAst*>(visitNode(node->v.Call.starargs));
|
|
+ nodeStack.pop();
|
|
+ v->arguments.append(starred);
|
|
+ nodeStack.pop();
|
|
+};
|
|
+if (node->v.Call.kwargs) {
|
|
+ nodeStack.push(v);
|
|
+ auto kwargs = new KeywordAst(v);
|
|
+ nodeStack.push(kwargs);
|
|
+ kwargs->value = static_cast<ExpressionAst*>(visitNode(node->v.Call.kwargs));
|
|
+ nodeStack.pop();
|
|
+ v->keywords.append(kwargs);
|
|
+ nodeStack.pop();
|
|
+};;
|
|
+RULE_FOR _expr;KIND Num_kind;ACTIONS create|NumberAst;BEFORE 3.8;CODE v->isInt = PyLong_Check(node->v.Num.n); v->value = PyLong_AsLong(node->v.Num.n);;
|
|
+RULE_FOR _expr;KIND Str_kind;ACTIONS create|StringAst set|value$>s;BEFORE 3.8;;
|
|
+RULE_FOR _expr;KIND JoinedStr_kind;ACTIONS create|JoinedStringAst set|values=>ExpressionAst,values;SINCE 3.6;;
|
|
+RULE_FOR _expr;KIND FormattedValue_kind;ACTIONS create|FormattedValueAst set|value->ExpressionAst,value set|conversion:>conversion set|formatSpec->ExpressionAst,format_spec;SINCE 3.6;;
|
|
+RULE_FOR _expr;KIND Bytes_kind;ACTIONS create|BytesAst set|value$>s;BEFORE 3.8;;
|
|
+RULE_FOR _expr;KIND Attribute_kind;ACTIONS create|AttributeAst set|attribute~>attr set|value->ExpressionAst,value set|context*>Context,ctx;;
|
|
+RULE_FOR _expr;KIND Subscript_kind;ACTIONS create|SubscriptAst set|value->ExpressionAst,value set|slice->SliceAst,slice set|context*>Context,ctx;;
|
|
+RULE_FOR _expr;KIND Starred_kind;ACTIONS create|StarredAst set|value->ExpressionAst,value set|context*>Context,ctx;;
|
|
+RULE_FOR _expr;KIND Name_kind;ACTIONS create|NameAst set|identifier~>id set|context*>Context,ctx;;
|
|
+RULE_FOR _expr;KIND List_kind;ACTIONS create|ListAst set|elements=>ExpressionAst,elts set|context*>Context,ctx;;
|
|
+RULE_FOR _expr;KIND Tuple_kind;ACTIONS create|TupleAst set|elements=>ExpressionAst,elts set|context*>Context,ctx;;
|
|
+RULE_FOR _expr;KIND Ellipsis_kind;ACTIONS create|EllipsisAst;BEFORE 3.8;;
|
|
+RULE_FOR _expr;KIND NameConstant_kind;ACTIONS create|NameConstantAst set|value_>value;BEFORE 3.8;;
|
|
+RULE_FOR _expr;KIND YieldFrom_kind;ACTIONS create|YieldFromAst set|value->ExpressionAst,value;;
|
|
+RULE_FOR _expr;KIND Constant_kind;ACTIONS;SINCE 3.8;CODE
|
|
+PyObject *value = node->v.Constant.value;
|
|
+if (value == Py_None) {
|
|
+ NameConstantAst* v = new NameConstantAst(parent());
|
|
+ v->value = NameConstantAst::None;
|
|
+ result = v;
|
|
+}
|
|
+else if (value == Py_True) {
|
|
+ NameConstantAst* v = new NameConstantAst(parent());
|
|
+ v->value = NameConstantAst::True;
|
|
+ result = v;
|
|
+}
|
|
+else if (value == Py_False) {
|
|
+ NameConstantAst* v = new NameConstantAst(parent());
|
|
+ v->value = NameConstantAst::False;
|
|
+ result = v;
|
|
+}
|
|
+else if (value->ob_type == &PyLong_Type) {
|
|
+ NumberAst* v = new NumberAst(parent());
|
|
+ v->isInt = true;
|
|
+ v->value = PyLong_AsLong(value);
|
|
+ result = v;
|
|
+}
|
|
+else if (value->ob_type == &PyFloat_Type || value->ob_type == &PyComplex_Type) {
|
|
+ result = new NumberAst(parent());
|
|
+}
|
|
+else if (value->ob_type == &PyUnicode_Type) {
|
|
+ StringAst* v = new StringAst(parent());
|
|
+ v->value = PyUnicodeObjectToQString(value);
|
|
+ result = v;
|
|
+}
|
|
+else if (value->ob_type == &PyBytes_Type) {
|
|
+ result = new BytesAst(parent());
|
|
+}
|
|
+else if (value->ob_type == &PyEllipsis_Type) {
|
|
+ result = new EllipsisAst(parent());
|
|
+}
|
|
+else {
|
|
+ qWarning() << "Unhandled constant type: " << value->ob_type->tp_name;
|
|
+ Q_ASSERT(false);
|
|
+};;
|
|
+RULE_FOR _expr;KIND NamedExpr_kind;ACTIONS create|AssignmentExpressionAst set|target->ExpressionAst,target set|value->ExpressionAst,value;SINCE 3.8;;
|
|
+
|
|
+RULE_FOR _slice;KIND Slice_kind;ACTIONS create|SliceAst set|lower->ExpressionAst,lower set|upper->ExpressionAst,upper set|step->ExpressionAst,step;;
|
|
+RULE_FOR _slice;KIND ExtSlice_kind;ACTIONS create|ExtendedSliceAst set|dims=>SliceAst,dims;;
|
|
+RULE_FOR _slice;KIND Index_kind;ACTIONS create|IndexAst set|value->ExpressionAst,value;;
|
|
+
|
|
+
|
|
+RULE_FOR _comprehension;KIND any;ACTIONS create|ComprehensionAst set|target->ExpressionAst,target set|iterator->ExpressionAst,iter set|conditions=>ExpressionAst,ifs;;
|
|
+RULE_FOR _excepthandler;KIND ExceptHandler_kind;ACTIONS create|ExceptionHandlerAst set|type->ExpressionAst,type set|name~>name set|body=>Ast,body;;
|
|
+RULE_FOR _arguments;KIND any;ACTIONS create|ArgumentsAst set|vararg->ArgAst,vararg set|kwarg->ArgAst,kwarg set|arguments=>ArgAst,args set|defaultValues=>ExpressionAst,defaults set|kwonlyargs=>ArgAst,kwonlyargs;BEFORE 3.8;;
|
|
+RULE_FOR _arguments;KIND any;ACTIONS create|ArgumentsAst set|vararg->ArgAst,vararg set|kwarg->ArgAst,kwarg set|arguments=>ArgAst,args set|defaultValues=>ExpressionAst,defaults set|kwonlyargs=>ArgAst,kwonlyargs set|posonlyargs=>ArgAst,posonlyargs;SINCE 3.8;;
|
|
+RULE_FOR _arg;KIND any;ACTIONS create|ArgAst set|argumentName~>arg set|annotation->ExpressionAst,annotation;;
|
|
+RULE_FOR _keyword;KIND any;ACTIONS create|KeywordAst set|argumentName~>arg set|value->ExpressionAst,value;;
|
|
+RULE_FOR _alias;KIND any;ACTIONS create|AliasAst set|name~>name set|asName~>asname;;
|
|
+RULE_FOR _withitem;KIND any; ACTIONS create|WithItemAst set|contextExpression->ExpressionAst,context_expr set|optionalVars->ExpressionAst,optional_vars;;
|
|
diff --git a/parser/tests/pyasttest.cpp b/parser/tests/pyasttest.cpp
|
|
index 4fd5f4e..c28f6fc 100644
|
|
--- a/parser/tests/pyasttest.cpp
|
|
+++ b/parser/tests/pyasttest.cpp
|
|
@@ -238,6 +238,11 @@ void PyAstTest::testExpressions_data()
|
|
" **{ext: self.res_extension for ext in self._rc_extensions + self._mc_extensions},\n"
|
|
"}";
|
|
#endif
|
|
+#if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0)
|
|
+ QTest::newRow("assignment_expr_1") << "a = (b := 10)";
|
|
+ QTest::newRow("assignment_expr_2") << "a = [q for z in (1, 2, 3) if (q := 2*z)]";
|
|
+ QTest::newRow("positional_params") << "def foo(a, b, /, c, d, *, e): pass";
|
|
+#endif
|
|
}
|
|
|
|
void PyAstTest::testCorrectedFuncRanges()
|
|
--
|
|
cgit v1.1
|
|
|