File indexing completed on 2024-05-19 15:42:35
0001 #include "asttransformer.h" 0002 #include "astbuilder.h" 0003 0004 namespace Python 0005 { 0006 0007 template <> 0008 QString AstTransformer::getattr(PyObject *obj, const char *attr) const 0009 { 0010 PyObject *v = PyObject_GetAttrString(obj, attr); 0011 // qDebug() << "getattr<str>: " << PyUnicodeObjectToQString(PyObject_Str(obj)) << "." << attr << "v=" << PyUnicodeObjectToQString(PyObject_Str(v)); 0012 Q_ASSERT(v); // attr missing 0013 if (PyUnicode_Check(v)) 0014 return PyUnicodeObjectToQString(v); 0015 Py_XDECREF(v); 0016 return ""; 0017 } 0018 0019 template <> 0020 bool AstTransformer::getattr(PyObject *obj, const char *attr) const 0021 { 0022 PyObject *v = PyObject_GetAttrString(obj, attr); 0023 // qDebug() << "getattr<bool>: " << PyUnicodeObjectToQString(PyObject_Str(obj)) << "." << attr; 0024 Q_ASSERT(v); // attr missing 0025 bool r = PyObject_IsTrue(v) == 1; 0026 Py_XDECREF(v); 0027 return r; 0028 } 0029 0030 template <> 0031 int AstTransformer::getattr(PyObject *obj, const char *attr) const 0032 { 0033 int result; 0034 PyObject *v = PyObject_GetAttrString(obj, attr); 0035 // qDebug() << "getattr<int>: " << PyUnicodeObjectToQString(PyObject_Str(obj)) << "." << attr << "v=" << PyUnicodeObjectToQString(PyObject_Str(v)); 0036 if (v && PyLong_Check(v)) { 0037 result = PyLong_AsLong(v); 0038 } else { 0039 result = 0; 0040 } 0041 Py_XDECREF(v); 0042 return result; 0043 } 0044 0045 0046 template <> 0047 PyObject* AstTransformer::getattr(PyObject *obj, const char *attr) const 0048 { 0049 // qDebug() << "getattr<obj>: " << PyUnicodeObjectToQString(PyObject_Str(obj)) << "." << attr;; 0050 PyObject* v = PyObject_GetAttrString(obj, attr); 0051 Q_ASSERT(v); // attr missing 0052 return v; 0053 } 0054 0055 template <> 0056 PyObjectRef AstTransformer::getattr(PyObject *obj, const char *attr) const 0057 { 0058 return getattr<PyObject*>(obj, attr); 0059 } 0060 0061 template <> 0062 ExpressionAst::Context AstTransformer::getattr(PyObject *obj, const char *attr) const 0063 { 0064 ExpressionAst::Context result; 0065 PyObject *v = PyObject_GetAttrString(obj, attr); 0066 // qDebug() << "getattr<expr:ctx>: " << PyUnicodeObjectToQString(PyObject_Str(obj)) << "." << attr<< "ctx: " << PyUnicodeObjectToQString(PyObject_Str(v)); 0067 Q_ASSERT(v); // attr missing 0068 if (PyObject_IsInstance(v, grammar.ast_Load)) 0069 result = ExpressionAst::Context::Load; 0070 else if (PyObject_IsInstance(v, grammar.ast_Store)) 0071 result = ExpressionAst::Context::Store; 0072 else if (PyObject_IsInstance(v, grammar.ast_Delete)) 0073 result = ExpressionAst::Context::Delete; 0074 else 0075 result = ExpressionAst::Context::Invalid; 0076 Py_XDECREF(v); 0077 return result; 0078 } 0079 0080 template <> 0081 Ast::OperatorTypes AstTransformer::getattr(PyObject *obj, const char *attr) const 0082 { 0083 Ast::OperatorTypes result; 0084 PyObject *op = PyObject_GetAttrString(obj, attr); 0085 // qDebug() << "getattr<expr:ctx>: " << PyUnicodeObjectToQString(PyObject_Str(obj)) << "." << attr<< "op: " << PyUnicodeObjectToQString(PyObject_Str(op)); 0086 Q_ASSERT(op); // attr missing 0087 if (PyObject_IsInstance(op, grammar.ast_Add)) 0088 result = Ast::OperatorAdd; 0089 else if (PyObject_IsInstance(op, grammar.ast_BitAnd)) 0090 result = Ast::OperatorBitwiseAnd; 0091 else if (PyObject_IsInstance(op, grammar.ast_BitOr)) 0092 result = Ast::OperatorBitwiseOr; 0093 else if (PyObject_IsInstance(op, grammar.ast_BitXor)) 0094 result = Ast::OperatorBitwiseXor; 0095 else if (PyObject_IsInstance(op, grammar.ast_Div)) 0096 result = Ast::OperatorDiv; 0097 else if (PyObject_IsInstance(op, grammar.ast_FloorDiv)) 0098 result = Ast::OperatorFloorDivision; 0099 else if (PyObject_IsInstance(op, grammar.ast_LShift)) 0100 result = Ast::OperatorLeftShift; 0101 else if (PyObject_IsInstance(op, grammar.ast_Mod)) 0102 result = Ast::OperatorMod; 0103 else if (PyObject_IsInstance(op, grammar.ast_Mult)) 0104 result = Ast::OperatorMult; 0105 else if (PyObject_IsInstance(op, grammar.ast_MatMult)) 0106 result = Ast::OperatorMatMult; 0107 else if (PyObject_IsInstance(op, grammar.ast_Pow)) 0108 result = Ast::OperatorPow; 0109 else if (PyObject_IsInstance(op, grammar.ast_RShift)) 0110 result = Ast::OperatorRightShift; 0111 else if (PyObject_IsInstance(op, grammar.ast_Sub)) 0112 result = Ast::OperatorSub; 0113 else 0114 result = Ast::OperatorInvalid; 0115 Py_XDECREF(op); 0116 return result; 0117 } 0118 0119 Ast* AstTransformer::visitModuleNode(PyObject* node, Ast* parent) 0120 { 0121 Q_UNUSED(parent); 0122 if (!PyObject_IsInstance(node, grammar.ast_Module)) return nullptr; 0123 CodeAst* ast = new CodeAst(); 0124 { 0125 // qDebug() << "Visit module: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0126 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 0127 ast->body = visitNodeList<Ast>(body, ast); 0128 } 0129 return ast; 0130 } 0131 0132 template<typename K> 0133 QList<K*> AstTransformer::visitNodeList(PyObject* node, Ast* parent) 0134 { 0135 // qDebug() << "visit list: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0136 QList<K*> nodelist; 0137 Q_ASSERT(PyList_Check(node)); 0138 for ( int i=0; i < PyList_Size(node); i++ ) 0139 { 0140 PyObject* currentNode = PyList_GetItem(node, i); 0141 Ast* result = visitNode(currentNode, parent); 0142 K* transformedNode = static_cast<K*>(result); 0143 nodelist.append(transformedNode); 0144 } 0145 // qDebug() << " size: " << nodelist.size(); 0146 return nodelist; 0147 } 0148 0149 Ast* AstTransformer::visitNode(PyObject* node, Ast* parent) 0150 { 0151 if ( ! node || node == Py_None ) return nullptr; 0152 // qDebug() << "visit node: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0153 0154 if (PyObject_IsInstance(node, grammar.ast_expr)) 0155 return visitExprNode(node, parent); 0156 if (PyObject_IsInstance(node, grammar.ast_stmt)) 0157 return visitStmtNode(node, parent); 0158 if (PyObject_IsInstance(node, grammar.ast_arg)) 0159 return visitArgNode(node, parent); 0160 if (PyObject_IsInstance(node, grammar.ast_comprehension)) 0161 return visitComprehensionNode(node, parent); 0162 if (PyObject_IsInstance(node, grammar.ast_arguments)) 0163 return visitArgumentsNode(node, parent); 0164 if (PyObject_IsInstance(node, grammar.ast_keyword)) 0165 return visitKeywordNode(node, parent); 0166 if (PyObject_IsInstance(node, grammar.ast_alias)) 0167 return visitAliasNode(node, parent); 0168 if (PyObject_IsInstance(node, grammar.ast_withitem)) 0169 return visitWithItemNode(node, parent); 0170 if (PyObject_IsInstance(node, grammar.ast_excepthandler)) 0171 return visitExceptHandlerNode(node, parent); 0172 if (PyObject_IsInstance(node, grammar.ast_slice)) 0173 return visitSliceNode(node, parent); 0174 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 10, 0) 0175 if (PyObject_IsInstance(node, grammar.ast_match_case)) 0176 return visitMatchCaseNode(node, parent); 0177 if (PyObject_IsInstance(node, grammar.ast_pattern)) 0178 return visitPatternNode(node, parent); 0179 #endif 0180 if (PyObject_IsInstance(node, grammar.ast_mod)) 0181 return visitModuleNode(node, parent); 0182 qWarning() << "Unsupported AST type: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0183 Q_UNREACHABLE(); 0184 } 0185 0186 Ast* AstTransformer::visitAliasNode(PyObject* node, Ast* parent) 0187 { 0188 if (!node) return nullptr; 0189 // qDebug() << "visit alias: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0190 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_alias)); 0191 AliasAst* v = new AliasAst(parent); 0192 v->name = new Python::Identifier(getattr<QString>(node, "name")); 0193 v->name->startLine = tline(getattr<int>(node, "lineno")); 0194 v->name->startCol = getattr<int>(node, "col_offset"); 0195 v->name->endCol = v->name->startCol + v->name->value.size() - 1; 0196 v->name->endLine = v->name->startLine; 0197 v->startLine = v->name->startLine;; 0198 v->startCol = v->name->startCol; 0199 v->endCol = v->name->endCol; 0200 v->endLine = v->name->endLine; 0201 QString asname = getattr<QString>(node, "asname"); 0202 v->asName = asname.size() ? new Python::Identifier(asname) : nullptr; 0203 return v; 0204 } 0205 0206 0207 Ast* AstTransformer::visitArgNode(PyObject* node, Ast* parent) 0208 { 0209 if (!node || node == Py_None) return nullptr; 0210 // qDebug() << "visit arg: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0211 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_arg)); 0212 ArgAst* v = new ArgAst(parent); 0213 QString arg = getattr<QString>(node, "arg"); 0214 if (arg.size()) { 0215 v->argumentName = new Python::Identifier(arg); 0216 v->argumentName->startCol = getattr<int>(node, "col_offset"); 0217 v->argumentName->startLine = tline(getattr<int>(node, "lineno")); 0218 v->argumentName->endCol = v->argumentName->startCol + arg.size() - 1; 0219 v->argumentName->endLine = v->argumentName->startLine; 0220 0221 v->startCol = v->argumentName->startCol; 0222 v->startLine = v->argumentName->startLine; 0223 v->endCol = v->argumentName->endCol; 0224 v->endLine = v->argumentName->endLine; 0225 } else { 0226 v->argumentName = nullptr; 0227 } 0228 { 0229 PyObjectRef annotation = getattr<PyObjectRef>(node, "annotation"); 0230 v->annotation = static_cast<ExpressionAst*>(visitExprNode(annotation, v)); 0231 } 0232 return v; 0233 } 0234 0235 Ast* AstTransformer::visitArgumentsNode(PyObject* node, Ast* parent) 0236 { 0237 if (!node || node == Py_None) return nullptr; 0238 // qDebug() << "visit args: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0239 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_arguments)); 0240 ArgumentsAst* v = new ArgumentsAst(parent); 0241 { 0242 PyObjectRef vararg = getattr<PyObjectRef>(node, "vararg"); 0243 v->vararg = static_cast<ArgAst*>(visitArgNode(vararg, v)); 0244 } 0245 { 0246 PyObjectRef kwarg = getattr<PyObjectRef>(node, "kwarg"); 0247 v->kwarg = static_cast<ArgAst*>(visitArgNode(kwarg, v)); 0248 } 0249 { 0250 PyObjectRef args = getattr<PyObjectRef>(node, "args"); 0251 v->arguments = visitNodeList<ArgAst>(args, v); 0252 } 0253 0254 { 0255 PyObjectRef defaults = getattr<PyObjectRef>(node, "defaults"); 0256 v->defaultValues = visitNodeList<ExpressionAst>(defaults, v); 0257 } 0258 0259 { 0260 PyObjectRef kwonlyargs = getattr<PyObjectRef>(node, "kwonlyargs"); 0261 v->kwonlyargs = visitNodeList<ArgAst>(kwonlyargs, v); 0262 } 0263 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0) 0264 { 0265 PyObjectRef posonlyargs = getattr<PyObjectRef>(node, "posonlyargs"); 0266 v->posonlyargs = visitNodeList<ArgAst>(posonlyargs, v); 0267 } 0268 #endif 0269 { 0270 PyObjectRef kw_defaults = getattr<PyObjectRef>(node, "kw_defaults"); 0271 v->defaultKwValues = visitNodeList<ExpressionAst>(kw_defaults, v); 0272 } 0273 0274 return v; 0275 } 0276 0277 Ast* AstTransformer::visitComprehensionNode(PyObject* node, Ast* parent) { 0278 if ( ! node || node == Py_None ) return nullptr; 0279 // qDebug() << "visit comp: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0280 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_comprehension)); 0281 ComprehensionAst* v = new ComprehensionAst(parent); 0282 { 0283 PyObjectRef target = getattr<PyObjectRef>(node, "target"); 0284 v->target = static_cast<ExpressionAst*>(visitExprNode(target, v)); 0285 } 0286 { 0287 PyObjectRef iter = getattr<PyObjectRef>(node, "iter"); 0288 v->iterator = static_cast<ExpressionAst*>(visitExprNode(iter, v)); 0289 } 0290 { 0291 PyObjectRef ifs = getattr<PyObjectRef>(node, "ifs"); 0292 v->conditions = visitNodeList<ExpressionAst>(ifs, v); 0293 } 0294 return v; 0295 } 0296 0297 Ast* AstTransformer::visitExceptHandlerNode(PyObject* node, Ast* parent) 0298 { 0299 if ( !node || node == Py_None ) return nullptr; 0300 // qDebug() << "visit except hdlr: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0301 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_excepthandler)); 0302 ExceptionHandlerAst* v = new ExceptionHandlerAst(parent); 0303 { 0304 PyObjectRef type = getattr<PyObjectRef>(node, "type"); 0305 v->type = static_cast<ExpressionAst*>(visitExprNode(type, v)); 0306 } 0307 QString name = getattr<QString>(node, "name"); 0308 if (name.size()) 0309 { 0310 v->name = new Python::Identifier(name); 0311 v->name->startCol = getattr<int>(node, "col_offset"); 0312 v->name->startLine = tline(getattr<int>(node, "lineno")); 0313 v->name->endCol = v->name->startCol + name.size() - 1; 0314 v->name->endLine = v->name->startLine; 0315 0316 v->startCol = v->name->startCol; 0317 v->startLine = v->name->startLine; 0318 v->endCol = v->name->endCol; 0319 v->endLine = v->name->endLine; 0320 } else { 0321 v->name = nullptr; 0322 } 0323 0324 { 0325 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 0326 v->body = visitNodeList<Ast>(body, v); 0327 } 0328 updateRanges(v); 0329 return v; 0330 } 0331 0332 Ast* AstTransformer::visitExprNode(PyObject* node, Ast* parent) 0333 { 0334 if (!node || node == Py_None) return nullptr; 0335 // qDebug() << "visit expr: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0336 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_expr)); 0337 Ast* result = nullptr; 0338 0339 bool ranges_copied = false; 0340 0341 if (PyObject_IsInstance(node, grammar.ast_Await)) { 0342 AwaitAst* v = new AwaitAst(parent); 0343 { 0344 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0345 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0346 } 0347 result = v; 0348 } 0349 else if (PyObject_IsInstance(node, grammar.ast_BoolOp)) { 0350 BooleanOperationAst* v = new BooleanOperationAst(parent); 0351 { 0352 PyObjectRef op = getattr<PyObjectRef>(node, "op"); 0353 if (PyObject_IsInstance(op, grammar.ast_And)) 0354 v->type = Ast::BooleanAnd; 0355 else if (PyObject_IsInstance(op, grammar.ast_Or)) 0356 v->type = Ast::BooleanOr; 0357 else 0358 v->type = Ast::BooleanInvalidOperation; 0359 } 0360 { 0361 PyObjectRef values = getattr<PyObjectRef>(node, "values"); 0362 v->values = visitNodeList<ExpressionAst>(values, v); 0363 } 0364 result = v; 0365 } 0366 else if (PyObject_IsInstance(node, grammar.ast_BinOp)) { 0367 BinaryOperationAst* v = new BinaryOperationAst(parent); 0368 v->type = getattr<Ast::OperatorTypes>(node, "op"); 0369 { 0370 PyObjectRef left = getattr<PyObjectRef>(node, "left"); 0371 v->lhs = static_cast<ExpressionAst*>(visitExprNode(left, v)); 0372 } 0373 { 0374 PyObjectRef right = getattr<PyObjectRef>(node, "right"); 0375 v->rhs = static_cast<ExpressionAst*>(visitExprNode(right, v)); 0376 } 0377 result = v; 0378 } 0379 else if (PyObject_IsInstance(node, grammar.ast_UnaryOp)) { 0380 UnaryOperationAst* v = new UnaryOperationAst(parent); 0381 { 0382 PyObjectRef op = getattr<PyObjectRef>(node, "op"); 0383 if (PyObject_IsInstance(op, grammar.ast_Invert)) 0384 v->type = Ast::UnaryOperatorInvert; 0385 else if (PyObject_IsInstance(op, grammar.ast_Not)) 0386 v->type = Ast::UnaryOperatorNot; 0387 else if (PyObject_IsInstance(op, grammar.ast_UAdd)) 0388 v->type = Ast::UnaryOperatorAdd; 0389 else if (PyObject_IsInstance(op, grammar.ast_USub)) 0390 v->type = Ast::UnaryOperatorSub; 0391 else 0392 v->type = Ast::UnaryOperatorInvalid; 0393 } 0394 { 0395 PyObjectRef operand = getattr<PyObjectRef>(node, "operand"); 0396 v->operand = static_cast<ExpressionAst*>(visitExprNode(operand, v)); 0397 } 0398 result = v; 0399 } 0400 else if (PyObject_IsInstance(node, grammar.ast_Lambda)) { 0401 LambdaAst* v = new LambdaAst(parent); 0402 { 0403 PyObjectRef args = getattr<PyObjectRef>(node, "args"); 0404 v->arguments = static_cast<ArgumentsAst*>(visitArgumentsNode(args, v)); 0405 } 0406 { 0407 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 0408 v->body = static_cast<ExpressionAst*>(visitExprNode(body, v)); 0409 } 0410 result = v; 0411 } 0412 else if (PyObject_IsInstance(node, grammar.ast_IfExp)) { 0413 IfExpressionAst* v = new IfExpressionAst(parent); 0414 { 0415 PyObjectRef test = getattr<PyObjectRef>(node, "test"); 0416 v->condition = static_cast<ExpressionAst*>(visitExprNode(test, v)); 0417 } 0418 { 0419 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 0420 v->body = static_cast<ExpressionAst*>(visitExprNode(body, v)); 0421 } 0422 { 0423 PyObjectRef orelse = getattr<PyObjectRef>(node, "orelse"); 0424 v->orelse = static_cast<ExpressionAst*>(visitExprNode(orelse, v)); 0425 } 0426 result = v; 0427 } 0428 else if (PyObject_IsInstance(node, grammar.ast_Dict)) { 0429 DictAst* v = new DictAst(parent); 0430 { 0431 PyObjectRef keys = getattr<PyObjectRef>(node, "keys"); 0432 v->keys = visitNodeList<ExpressionAst>(keys, v); 0433 } 0434 { 0435 PyObjectRef values = getattr<PyObjectRef>(node, "values"); 0436 v->values = visitNodeList<ExpressionAst>(values, v); 0437 } 0438 result = v; 0439 } 0440 else if (PyObject_IsInstance(node, grammar.ast_Set)) { 0441 SetAst* v = new SetAst(parent); 0442 { 0443 PyObjectRef elts = getattr<PyObjectRef>(node, "elts"); 0444 v->elements = visitNodeList<ExpressionAst>(elts, v); 0445 } 0446 result = v; 0447 } 0448 else if (PyObject_IsInstance(node, grammar.ast_ListComp)) { 0449 ListComprehensionAst* v = new ListComprehensionAst(parent); 0450 { 0451 PyObjectRef elt = getattr<PyObjectRef>(node, "elt"); 0452 v->element = static_cast<ExpressionAst*>(visitExprNode(elt, v)); 0453 } 0454 { 0455 PyObjectRef generators = getattr<PyObjectRef>(node, "generators"); 0456 v->generators = visitNodeList<ComprehensionAst>(generators, v); 0457 } 0458 result = v; 0459 } 0460 else if (PyObject_IsInstance(node, grammar.ast_SetComp)) { 0461 SetComprehensionAst* v = new SetComprehensionAst(parent); 0462 { 0463 PyObjectRef elt = getattr<PyObjectRef>(node, "elt"); 0464 v->element = static_cast<ExpressionAst*>(visitExprNode(elt, v)); 0465 } 0466 { 0467 PyObjectRef generators = getattr<PyObjectRef>(node, "generators"); 0468 v->generators = visitNodeList<ComprehensionAst>(generators, v); 0469 } 0470 result = v; 0471 } 0472 else if (PyObject_IsInstance(node, grammar.ast_DictComp)) { 0473 DictionaryComprehensionAst* v = new DictionaryComprehensionAst(parent); 0474 { 0475 PyObjectRef key = getattr<PyObjectRef>(node, "key"); 0476 v->key = static_cast<ExpressionAst*>(visitExprNode(key, v)); 0477 } 0478 { 0479 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0480 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0481 } 0482 { 0483 PyObjectRef generators = getattr<PyObjectRef>(node, "generators"); 0484 v->generators = visitNodeList<ComprehensionAst>(generators, v); 0485 } 0486 result = v; 0487 } 0488 else if (PyObject_IsInstance(node, grammar.ast_GeneratorExp)) { 0489 GeneratorExpressionAst* v = new GeneratorExpressionAst(parent); 0490 { 0491 PyObjectRef elt = getattr<PyObjectRef>(node, "elt"); 0492 v->element = static_cast<ExpressionAst*>(visitExprNode(elt, v)); 0493 } 0494 { 0495 PyObjectRef generators = getattr<PyObjectRef>(node, "generators"); 0496 v->generators = visitNodeList<ComprehensionAst>(generators, v); 0497 0498 } 0499 result = v; 0500 } 0501 else if (PyObject_IsInstance(node, grammar.ast_Yield)) { 0502 YieldAst* v = new YieldAst(parent); 0503 { 0504 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0505 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0506 } 0507 result = v; 0508 } 0509 else if (PyObject_IsInstance(node, grammar.ast_Compare)) { 0510 CompareAst* v = new CompareAst(parent); 0511 { 0512 PyObjectRef left = getattr<PyObjectRef>(node, "left"); 0513 v->leftmostElement = static_cast<ExpressionAst*>(visitExprNode(left, v)); 0514 } 0515 0516 { 0517 PyObject* ops = getattr<PyObject*>(node, "ops"); 0518 Q_ASSERT(PyList_Check(ops)); 0519 for ( int _i = 0; _i < PyList_Size(ops); _i++ ) { 0520 PyObject* elt = PyList_GET_ITEM(ops, _i); // borrowed 0521 ExpressionAst::ComparisonOperatorTypes cmp; 0522 if (PyObject_IsInstance(elt, grammar.ast_Eq)) 0523 cmp = Ast::ComparisonOperatorEquals; 0524 else if (PyObject_IsInstance(elt, grammar.ast_NotEq)) 0525 cmp = Ast::ComparisonOperatorNotEquals; 0526 else if (PyObject_IsInstance(elt, grammar.ast_Lt)) 0527 cmp = Ast::ComparisonOperatorLessThan; 0528 else if (PyObject_IsInstance(elt, grammar.ast_LtE)) 0529 cmp = Ast::ComparisonOperatorLessThanEqual; 0530 else if (PyObject_IsInstance(elt, grammar.ast_Gt)) 0531 cmp = Ast::ComparisonOperatorGreaterThan; 0532 else if (PyObject_IsInstance(elt, grammar.ast_GtE)) 0533 cmp = Ast::ComparisonOperatorGreaterThanEqual; 0534 else if (PyObject_IsInstance(elt, grammar.ast_Is)) 0535 cmp = Ast::ComparisonOperatorIs; 0536 else if (PyObject_IsInstance(elt, grammar.ast_IsNot)) 0537 cmp = Ast::ComparisonOperatorIsNot; 0538 else if (PyObject_IsInstance(elt, grammar.ast_In)) 0539 cmp = Ast::ComparisonOperatorIn; 0540 else if (PyObject_IsInstance(elt, grammar.ast_NotIn)) 0541 cmp = Ast::ComparisonOperatorNotIn; 0542 else 0543 cmp = Ast::ComparisonOperatorInvalid; 0544 v->operators.append(cmp); 0545 } 0546 Py_DECREF(ops); 0547 } 0548 0549 { 0550 PyObjectRef comparators = getattr<PyObjectRef>(node, "comparators"); 0551 v->comparands = visitNodeList<ExpressionAst>(comparators, v); 0552 } 0553 result = v; 0554 } 0555 else if (PyObject_IsInstance(node, grammar.ast_Call)) { 0556 CallAst* v = new CallAst(parent); 0557 { 0558 PyObjectRef func = getattr<PyObjectRef>(node, "func"); 0559 v->function = static_cast<ExpressionAst*>(visitExprNode(func, v)); 0560 } 0561 { 0562 PyObjectRef args = getattr<PyObjectRef>(node, "args"); 0563 v->arguments = visitNodeList<ExpressionAst>(args, v); 0564 } 0565 { 0566 PyObjectRef keywords = getattr<PyObjectRef>(node, "keywords"); 0567 v->keywords = visitNodeList<KeywordAst>(keywords, v); 0568 } 0569 #if PYTHON_VERSION < QT_VERSION_CHECK(3, 5, 0) 0570 /* Convert 3.4 unpacked-args AST to match the new format from 3.5+ */ 0571 // TODO 0572 #endif 0573 result = v; 0574 } 0575 #if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0) 0576 else if (PyObject_IsInstance(node, grammar.ast_Num)) { 0577 NumberAst* v = new NumberAst(parent); 0578 { 0579 PyObjectRef n = getattr<PyObjectRef>(node, "n"); 0580 v->isInt = PyLong_Check(n); 0581 v->value = PyLong_AsLong(n); 0582 } 0583 result = v; 0584 } 0585 #endif 0586 #if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0) 0587 else if (PyObject_IsInstance(node, grammar.ast_Str)) { 0588 StringAst* v = new StringAst(parent); 0589 v->value = getattr<QString>(node, "s"); 0590 result = v; 0591 } 0592 #endif 0593 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0) 0594 else if (PyObject_IsInstance(node, grammar.ast_JoinedStr)) { 0595 JoinedStringAst* v = new JoinedStringAst(parent); 0596 { 0597 PyObjectRef values = getattr<PyObjectRef>(node, "values"); 0598 v->values = visitNodeList<ExpressionAst>(values, v); 0599 } 0600 result = v; 0601 } 0602 #endif 0603 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0) 0604 else if (PyObject_IsInstance(node, grammar.ast_FormattedValue)) { 0605 FormattedValueAst* v = new FormattedValueAst(parent); 0606 { 0607 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0608 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0609 0610 } 0611 v->conversion = getattr<int>(node, "conversion"); 0612 { 0613 PyObjectRef format_spec = getattr<PyObjectRef>(node, "format_spec"); 0614 v->formatSpec = static_cast<ExpressionAst*>(visitExprNode(format_spec, v)); 0615 } 0616 result = v; 0617 } 0618 #endif 0619 #if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0) 0620 else if (PyObject_IsInstance(node, grammar.ast_Bytes)) { 0621 BytesAst* v = new BytesAst(parent); 0622 v->value = getattr<QString>(node, "s"); 0623 result = v; 0624 } 0625 #endif 0626 else if (PyObject_IsInstance(node, grammar.ast_Attribute)) { 0627 AttributeAst* v = new AttributeAst(parent); 0628 QString attr = getattr<QString>(node, "attr"); 0629 if (attr.size()) { 0630 v->attribute = new Python::Identifier(attr); 0631 v->attribute->startCol = getattr<int>(node, "col_offset"); 0632 v->attribute->startLine = tline(getattr<int>(node, "lineno")); 0633 v->attribute->endCol = v->attribute->startCol + attr.size() - 1; 0634 v->attribute->endLine = v->attribute->startLine; 0635 0636 v->startCol = v->attribute->startCol; 0637 v->startLine = v->attribute->startLine; 0638 v->endCol = v->attribute->endCol; 0639 v->endLine = v->attribute->endLine; 0640 ranges_copied = true; 0641 } else { 0642 v->attribute = nullptr; 0643 } 0644 { 0645 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0646 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0647 } 0648 v->context = getattr<ExpressionAst::Context>(node, "ctx"); 0649 result = v; 0650 } 0651 else if (PyObject_IsInstance(node, grammar.ast_Subscript)) { 0652 SubscriptAst* v = new SubscriptAst(parent); 0653 { 0654 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0655 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0656 } 0657 { 0658 PyObjectRef slice = getattr<PyObjectRef>(node, "slice"); 0659 v->slice = static_cast<SliceAst*>(visitNode(slice, v)); 0660 } 0661 v->context = getattr<ExpressionAst::Context>(node, "ctx"); 0662 result = v; 0663 } 0664 else if (PyObject_IsInstance(node, grammar.ast_Starred)) { 0665 StarredAst* v = new StarredAst(parent); 0666 { 0667 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0668 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0669 } 0670 v->context = getattr<ExpressionAst::Context>(node, "ctx"); 0671 result = v; 0672 } 0673 else if (PyObject_IsInstance(node, grammar.ast_Name)) { 0674 NameAst* v = new NameAst(parent); 0675 QString id = getattr<QString>(node, "id"); 0676 if ( id.size() ) { 0677 v->identifier = new Python::Identifier(id); 0678 v->identifier->startCol = getattr<int>(node, "col_offset"); 0679 v->identifier->startLine = tline(getattr<int>(node, "lineno")); 0680 v->identifier->endCol = v->identifier->startCol + id.size() - 1; 0681 v->identifier->endLine = v->identifier->startLine; 0682 v->startCol = v->identifier->startCol; 0683 v->startLine = v->identifier->startLine; 0684 v->endCol = v->identifier->endCol; 0685 v->endLine = v->identifier->endLine; 0686 ranges_copied = true; 0687 } else { 0688 v->identifier = nullptr; 0689 } 0690 v->context = getattr<ExpressionAst::Context>(node, "ctx"); 0691 result = v; 0692 } 0693 else if (PyObject_IsInstance(node, grammar.ast_List)) { 0694 ListAst* v = new ListAst(parent); 0695 { 0696 PyObjectRef elts = getattr<PyObjectRef>(node, "elts"); 0697 v->elements = visitNodeList<ExpressionAst>(elts, v); 0698 } 0699 v->context = getattr<ExpressionAst::Context>(node, "ctx"); 0700 result = v; 0701 } 0702 else if (PyObject_IsInstance(node, grammar.ast_Tuple)) { 0703 TupleAst* v = new TupleAst(parent); 0704 { 0705 PyObjectRef elts = getattr<PyObjectRef>(node, "elts"); 0706 v->elements = visitNodeList<ExpressionAst>(elts, v); 0707 } 0708 v->context = getattr<ExpressionAst::Context>(node, "ctx"); 0709 result = v; 0710 } 0711 #if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0) 0712 else if (PyObject_IsInstance(node, grammar.ast_Ellipsis)) { 0713 EllipsisAst* v = new EllipsisAst(parent); 0714 result = v; 0715 } 0716 #endif 0717 #if PYTHON_VERSION < QT_VERSION_CHECK(3, 8, 0) 0718 else if (PyObject_IsInstance(node, grammar.ast_NameConstant)) { 0719 NameConstantAst* v = new NameConstantAst(parent); 0720 { 0721 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0722 if (value == Py_None) 0723 v->value = NameConstantAst::None; 0724 else if (value == Py_False) 0725 v->value = NameConstantAst::False; 0726 else 0727 v->value = NameConstantAst::True; 0728 } 0729 result = v; 0730 } 0731 #endif 0732 else if (PyObject_IsInstance(node, grammar.ast_YieldFrom)) { 0733 YieldFromAst* v = new YieldFromAst(parent); 0734 { 0735 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0736 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0737 } 0738 result = v; 0739 } 0740 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0) 0741 else if (PyObject_IsInstance(node, grammar.ast_Constant)) { 0742 PyObject* value = getattr<PyObject*>(node, "value"); 0743 if (value == Py_None) { 0744 NameConstantAst* v = new NameConstantAst(parent); 0745 v->value = NameConstantAst::None; 0746 result = v; 0747 0748 } else if (value == Py_True) { 0749 NameConstantAst* v = new NameConstantAst(parent); 0750 v->value = NameConstantAst::True; 0751 result = v; 0752 0753 } else if (value == Py_False) { 0754 NameConstantAst* v = new NameConstantAst(parent); 0755 v->value = NameConstantAst::False; 0756 result = v; 0757 0758 } else if (value->ob_type == &PyLong_Type) { 0759 NumberAst* v = new NumberAst(parent); 0760 v->isInt = true; 0761 v->value = PyLong_AsLong(value); 0762 result = v; 0763 } else if (value->ob_type == &PyFloat_Type || value->ob_type == &PyComplex_Type) { 0764 result = new NumberAst(parent); 0765 0766 } else if (value->ob_type == &PyUnicode_Type) { 0767 StringAst* v = new StringAst(parent); 0768 v->value = PyUnicodeObjectToQString(value); 0769 result = v; 0770 } else if (value->ob_type == &PyBytes_Type) { 0771 result = new BytesAst(parent); 0772 } else if (value->ob_type == &PyEllipsis_Type) { 0773 result = new EllipsisAst(parent); 0774 } else { 0775 qWarning() << "Unhandled constant type: " << value->ob_type->tp_name; 0776 Q_ASSERT(false); 0777 0778 }; 0779 Py_DECREF(value); 0780 } 0781 #endif 0782 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 8, 0) 0783 else if (PyObject_IsInstance(node, grammar.ast_NamedExpr)) { 0784 AssignmentExpressionAst* v = new AssignmentExpressionAst(parent); 0785 { 0786 PyObjectRef target = getattr<PyObjectRef>(node, "target"); 0787 v->target = static_cast<ExpressionAst*>(visitExprNode(target, v)); 0788 } 0789 { 0790 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0791 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0792 } 0793 result = v; 0794 } 0795 #endif 0796 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 9, 0) 0797 else if (PyObject_IsInstance(node, grammar.ast_Slice)) { 0798 SliceAst* v = new SliceAst(parent); 0799 { 0800 PyObjectRef lower = getattr<PyObjectRef>(node, "lower"); 0801 v->lower = static_cast<ExpressionAst*>(visitExprNode(lower, v)); 0802 } 0803 { 0804 PyObjectRef upper = getattr<PyObjectRef>(node, "upper"); 0805 v->upper = static_cast<ExpressionAst*>(visitExprNode(upper, v)); 0806 } 0807 { 0808 PyObjectRef step = getattr<PyObjectRef>(node, "step"); 0809 v->step = static_cast<ExpressionAst*>(visitExprNode(step, v)); 0810 } 0811 result = v; 0812 } 0813 #endif 0814 else { 0815 qWarning() << "Unsupported _expr AST type: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0816 Q_ASSERT(false); 0817 } 0818 0819 if ( ! result ) return nullptr; 0820 if ( ! ranges_copied ) { 0821 result->startCol = getattr<int>(node, "col_offset"); 0822 result->endCol = result->startCol; 0823 result->startLine = tline(getattr<int>(node, "lineno")); 0824 result->endLine = result->startLine; 0825 result->hasUsefulRangeInformation = true; 0826 } 0827 else { 0828 result->hasUsefulRangeInformation = true; 0829 } 0830 updateRanges(result); 0831 return result; 0832 } 0833 0834 0835 Ast* AstTransformer::visitSliceNode(PyObject* node, Ast* parent) 0836 { 0837 if ( ! node || node == Py_None ) return nullptr; 0838 // qDebug() << "visit slice: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0839 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_slice)); 0840 Ast* result = nullptr; 0841 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 9, 0) 0842 if (PyObject_IsInstance(node, grammar.ast_Slice)) { 0843 SliceAst* v = new SliceAst(parent); 0844 { 0845 PyObjectRef lower = getattr<PyObjectRef>(node, "lower"); 0846 v->lower = static_cast<ExpressionAst*>(visitExprNode(lower, v)); 0847 } 0848 { 0849 PyObjectRef upper = getattr<PyObjectRef>(node, "upper"); 0850 v->upper = static_cast<ExpressionAst*>(visitExprNode(upper, v)); 0851 } 0852 { 0853 PyObjectRef step = getattr<PyObjectRef>(node, "step"); 0854 v->step = static_cast<ExpressionAst*>(visitExprNode(step, v)); 0855 } 0856 result = v; 0857 } 0858 #endif 0859 #if PYTHON_VERSION < QT_VERSION_CHECK(3, 9, 0) 0860 if (PyObject_IsInstance(node, grammar.ast_ExtSlice)) { 0861 TupleAst* v = new TupleAst(parent); 0862 { 0863 PyObjectRef dims = getattr<PyObjectRef>(node, "dims"); 0864 v->elements = visitNodeList<ExpressionAst>(dims, parent); 0865 } 0866 result = v; 0867 } 0868 else if (PyObject_IsInstance(node, grammar.ast_Index)) { 0869 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0870 return visitNode(value, parent); 0871 } 0872 #endif 0873 else { 0874 qWarning() << "Unsupported _slice AST type: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0875 Q_ASSERT(false); 0876 } 0877 updateRanges(result); 0878 return result; 0879 } 0880 0881 Ast* AstTransformer::visitStmtNode(PyObject* node, Ast* parent) 0882 { 0883 if ( !node || node == Py_None ) return nullptr; 0884 // qDebug() << "visit stmt: " << PyUnicodeObjectToQString(PyObject_Str(node)); 0885 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_stmt)); 0886 bool ranges_copied = false; 0887 Ast* result = nullptr; 0888 if (PyObject_IsInstance(node, grammar.ast_Expr)) { 0889 ExpressionAst* v = new ExpressionAst(parent); 0890 { 0891 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0892 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0893 } 0894 result = v; 0895 } 0896 else if (PyObject_IsInstance(node, grammar.ast_FunctionDef) 0897 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0) 0898 || PyObject_IsInstance(node, grammar.ast_AsyncFunctionDef) 0899 #endif 0900 ) { 0901 FunctionDefinitionAst* v = new FunctionDefinitionAst(parent); 0902 QString name = getattr<QString>(node, "name"); 0903 if ( name.size() ) { 0904 v->name = new Python::Identifier(name); 0905 v->name->startCol = getattr<int>(node, "col_offset"); 0906 v->name->startLine = tline(getattr<int>(node, "lineno")); 0907 v->name->endCol = v->name->startCol + name.size() - 1; 0908 v->name->endLine = v->name->startLine; 0909 0910 v->startCol = v->name->startCol; 0911 v->startLine = v->name->startLine; 0912 v->endCol = v->name->endCol; 0913 v->endLine = v->name->endLine; 0914 ranges_copied = true; 0915 } 0916 else { 0917 v->name = nullptr; 0918 } 0919 0920 { 0921 PyObjectRef args = getattr<PyObjectRef>(node, "args"); 0922 v->arguments = static_cast<ArgumentsAst*>(visitArgumentsNode(args, v)); 0923 } 0924 { 0925 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 0926 v->body = visitNodeList<Ast>(body, v); 0927 } 0928 { 0929 PyObjectRef decorator_list = getattr<PyObjectRef>(node, "decorator_list"); 0930 v->decorators = visitNodeList<ExpressionAst>(decorator_list, v); 0931 } 0932 { 0933 PyObjectRef returns = getattr<PyObjectRef>(node, "returns"); 0934 v->returns = static_cast<ExpressionAst*>(visitExprNode(returns, v)); 0935 } 0936 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0) 0937 v->async = PyObject_IsInstance(node, grammar.ast_AsyncFunctionDef); 0938 #endif 0939 result = v; 0940 } 0941 else if (PyObject_IsInstance(node, grammar.ast_ClassDef)) { 0942 ClassDefinitionAst* v = new ClassDefinitionAst(parent); 0943 QString name = getattr<QString>(node, "name"); 0944 if ( name.size() ) { 0945 v->name = new Python::Identifier(name); 0946 v->name->startCol = getattr<int>(node, "col_offset"); 0947 v->name->startLine = tline(getattr<int>(node, "lineno")); 0948 v->name->endCol = v->name->startCol + name.size() - 1; 0949 v->name->endLine = v->name->startLine; 0950 0951 v->startCol = v->name->startCol; 0952 v->startLine = v->name->startLine; 0953 v->endCol = v->name->endCol; 0954 v->endLine = v->name->endLine; 0955 ranges_copied = true; 0956 } 0957 else { 0958 v->name = nullptr; 0959 } 0960 0961 { 0962 PyObjectRef bases = getattr<PyObjectRef>(node, "bases"); 0963 v->baseClasses = visitNodeList<ExpressionAst>(bases, v); 0964 } 0965 { 0966 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 0967 v->body = visitNodeList<Ast>(body, v); 0968 } 0969 { 0970 PyObjectRef decorator_list = getattr<PyObjectRef>(node, "decorator_list"); 0971 v->decorators = visitNodeList<ExpressionAst>(decorator_list, v); 0972 } 0973 result = v; 0974 } 0975 else if (PyObject_IsInstance(node, grammar.ast_Return)) { 0976 ReturnAst* v = new ReturnAst(parent); 0977 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0978 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0979 result = v; 0980 } 0981 else if (PyObject_IsInstance(node, grammar.ast_Delete)) { 0982 DeleteAst* v = new DeleteAst(parent); 0983 PyObjectRef targets = getattr<PyObjectRef>(node, "targets"); 0984 v->targets = visitNodeList<ExpressionAst>(targets, v); 0985 result = v; 0986 } 0987 else if (PyObject_IsInstance(node, grammar.ast_Assign)) { 0988 AssignmentAst* v = new AssignmentAst(parent); 0989 { 0990 PyObjectRef targets = getattr<PyObjectRef>(node, "targets"); 0991 v->targets = visitNodeList<ExpressionAst>(targets, v); 0992 } 0993 { 0994 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 0995 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 0996 } 0997 result = v; 0998 } 0999 else if (PyObject_IsInstance(node, grammar.ast_AugAssign)) { 1000 AugmentedAssignmentAst* v = new AugmentedAssignmentAst(parent); 1001 { 1002 PyObjectRef target = getattr<PyObjectRef>(node, "target"); 1003 v->target = static_cast<ExpressionAst*>(visitExprNode(target, v)); 1004 } 1005 v->op = getattr<Ast::OperatorTypes>(node, "op"); 1006 { 1007 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 1008 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 1009 } 1010 result = v; 1011 } 1012 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0) 1013 else if (PyObject_IsInstance(node, grammar.ast_AnnAssign)) { 1014 AnnotationAssignmentAst* v = new AnnotationAssignmentAst(parent); 1015 { 1016 PyObjectRef target = getattr<PyObjectRef>(node, "target"); 1017 v->target = static_cast<ExpressionAst*>(visitExprNode(target, v)); 1018 } 1019 { 1020 PyObjectRef annotation = getattr<PyObjectRef>(node, "annotation"); 1021 v->annotation = static_cast<ExpressionAst*>(visitExprNode(annotation, v)); 1022 } 1023 { 1024 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 1025 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 1026 } 1027 result = v; 1028 } 1029 #endif 1030 else if (PyObject_IsInstance(node, grammar.ast_For) 1031 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0) 1032 || PyObject_IsInstance(node, grammar.ast_AsyncFor) 1033 #endif 1034 ) { 1035 ForAst* v = new ForAst(parent); 1036 { 1037 PyObjectRef target = getattr<PyObjectRef>(node, "target"); 1038 v->target = static_cast<ExpressionAst*>(visitExprNode(target, v)); 1039 } 1040 { 1041 PyObjectRef iter = getattr<PyObjectRef>(node, "iter"); 1042 v->iterator = static_cast<ExpressionAst*>(visitExprNode(iter, v)); 1043 } 1044 { 1045 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 1046 v->body = visitNodeList<Ast>(body, v); 1047 } 1048 { 1049 PyObjectRef orelse = getattr<PyObjectRef>(node, "orelse"); 1050 v->orelse = visitNodeList<Ast>(orelse, v); 1051 } 1052 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0) 1053 v->async = PyObject_IsInstance(node, grammar.ast_AsyncFor); 1054 #endif 1055 result = v; 1056 } 1057 else if (PyObject_IsInstance(node, grammar.ast_While)) { 1058 WhileAst* v = new WhileAst(parent); 1059 { 1060 PyObjectRef test = getattr<PyObjectRef>(node, "test"); 1061 v->condition = static_cast<ExpressionAst*>(visitExprNode(test, v)); 1062 } 1063 { 1064 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 1065 v->body = visitNodeList<Ast>(body, v); 1066 } 1067 { 1068 PyObjectRef orelse = getattr<PyObjectRef>(node, "orelse"); 1069 v->orelse = visitNodeList<Ast>(orelse, v); 1070 } 1071 result = v; 1072 } 1073 else if (PyObject_IsInstance(node, grammar.ast_If)) { 1074 IfAst* v = new IfAst(parent); 1075 { 1076 PyObjectRef test = getattr<PyObjectRef>(node, "test"); 1077 v->condition = static_cast<ExpressionAst*>(visitExprNode(test, v)); 1078 } 1079 { 1080 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 1081 v->body = visitNodeList<Ast>(body, v); 1082 } 1083 { 1084 PyObjectRef orelse = getattr<PyObjectRef>(node, "orelse"); 1085 v->orelse = visitNodeList<Ast>(orelse, v); 1086 } 1087 result = v; 1088 } 1089 else if (PyObject_IsInstance(node, grammar.ast_With) 1090 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 6, 0) 1091 || PyObject_IsInstance(node, grammar.ast_AsyncWith) 1092 #endif 1093 ) { 1094 WithAst* v = new WithAst(parent); 1095 { 1096 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 1097 v->body = visitNodeList<Ast>(body, v); 1098 } 1099 { 1100 PyObjectRef items = getattr<PyObjectRef>(node, "items"); 1101 v->items = visitNodeList<WithItemAst>(items, v); 1102 } 1103 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 5, 0) 1104 v->async = PyObject_IsInstance(node, grammar.ast_AsyncWith); 1105 #endif 1106 result = v; 1107 } 1108 1109 else if (PyObject_IsInstance(node, grammar.ast_Raise)) { 1110 RaiseAst* v = new RaiseAst(parent); 1111 { 1112 PyObjectRef exc = getattr<PyObjectRef>(node, "exc"); 1113 v->type = static_cast<ExpressionAst*>(visitExprNode(exc, v)); 1114 } 1115 result = v; 1116 } 1117 else if (PyObject_IsInstance(node, grammar.ast_Try)) { 1118 TryAst* v = new TryAst(parent); 1119 { 1120 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 1121 v->body = visitNodeList<Ast>(body, v); 1122 } 1123 { 1124 PyObjectRef handlers = getattr<PyObjectRef>(node, "handlers"); 1125 v->handlers = visitNodeList<ExceptionHandlerAst>(handlers, v); 1126 1127 } 1128 { 1129 PyObjectRef orelse = getattr<PyObjectRef>(node, "orelse"); 1130 v->orelse = visitNodeList<Ast>(orelse, v); 1131 } 1132 { 1133 PyObjectRef finalbody = getattr<PyObjectRef>(node, "finalbody"); 1134 v->finally = visitNodeList<Ast>(finalbody, v); 1135 } 1136 result = v; 1137 } 1138 else if (PyObject_IsInstance(node, grammar.ast_Assert)) { 1139 AssertionAst* v = new AssertionAst(parent); 1140 { 1141 PyObjectRef test = getattr<PyObjectRef>(node, "test"); 1142 v->condition = static_cast<ExpressionAst*>(visitExprNode(test, v)); 1143 } 1144 { 1145 PyObjectRef msg = getattr<PyObjectRef>(node, "msg"); 1146 v->message = static_cast<ExpressionAst*>(visitExprNode(msg, v)); 1147 } 1148 result = v; 1149 } 1150 else if (PyObject_IsInstance(node, grammar.ast_Import)) { 1151 ImportAst* v = new ImportAst(parent); 1152 { 1153 PyObjectRef names = getattr<PyObjectRef>(node, "names"); 1154 v->names = visitNodeList<AliasAst>(names, v); 1155 } 1156 result = v; 1157 } 1158 else if (PyObject_IsInstance(node, grammar.ast_ImportFrom)) { 1159 ImportFromAst* v = new ImportFromAst(parent); 1160 QString module = getattr<QString>(node, "module"); 1161 if ( module.size() ) { 1162 v->module = new Python::Identifier(module); 1163 v->module->startCol = getattr<int>(node, "col_offset"); 1164 v->module->startLine = tline(getattr<int>(node, "lineno")); 1165 v->module->endCol = v->module->startCol + module.size() - 1; 1166 v->module->endLine = v->module->startLine; 1167 1168 v->startCol = v->module->startCol; 1169 v->startLine = v->module->startLine; 1170 v->endCol = v->module->endCol; 1171 v->endLine = v->module->endLine; 1172 ranges_copied = true; 1173 } else { 1174 v->module = nullptr; 1175 } 1176 { 1177 PyObjectRef names = getattr<PyObjectRef>(node, "names"); 1178 v->names = visitNodeList<AliasAst>(names, v); 1179 } 1180 v->level = getattr<int>(node, "level"); 1181 result = v; 1182 } 1183 else if (PyObject_IsInstance(node, grammar.ast_Global)) { 1184 GlobalAst* v = new GlobalAst(parent); 1185 1186 PyObject* names = getattr<PyObject*>(node, "names"); 1187 Q_ASSERT(PyList_Check(names)); 1188 for ( int _i = 0; _i < PyList_Size(names); _i++ ) { 1189 Python::Identifier* id = new Python::Identifier(PyUnicodeObjectToQString( 1190 static_cast<PyObject*>(PyList_GET_ITEM(names, _i)) 1191 )); 1192 v->names.append(id); 1193 } 1194 Py_DECREF(names); 1195 1196 result = v; 1197 } 1198 else if (PyObject_IsInstance(node, grammar.ast_Break)) { 1199 BreakAst* v = new BreakAst(parent); 1200 result = v; 1201 } 1202 else if (PyObject_IsInstance(node, grammar.ast_Continue)) { 1203 ContinueAst* v = new ContinueAst(parent); 1204 result = v; 1205 } 1206 else if (PyObject_IsInstance(node, grammar.ast_Pass)) { 1207 PassAst* v = new PassAst(parent); 1208 result = v; 1209 } 1210 else if (PyObject_IsInstance(node, grammar.ast_Nonlocal)) { 1211 NonlocalAst* v = new NonlocalAst(parent); 1212 result = v; 1213 } 1214 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 10, 0) 1215 else if (PyObject_IsInstance(node, grammar.ast_Match)) { 1216 MatchAst* v = new MatchAst(parent); 1217 { 1218 PyObjectRef subject = getattr<PyObjectRef>(node, "subject"); 1219 v->subject = static_cast<ExpressionAst*>(visitExprNode(subject, v)); 1220 } 1221 { 1222 PyObjectRef cases = getattr<PyObjectRef>(node, "cases"); 1223 v->cases = visitNodeList<MatchCaseAst>(cases, v); 1224 } 1225 result = v; 1226 } 1227 #endif 1228 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 11, 0) 1229 else if (PyObject_IsInstance(node, grammar.ast_TryStar)) { 1230 TryStarAst* v = new TryStarAst(parent); 1231 { 1232 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 1233 v->body = visitNodeList<Ast>(body, v); 1234 } 1235 { 1236 PyObjectRef handlers = getattr<PyObjectRef>(node, "handlers"); 1237 v->handlers = visitNodeList<ExceptionHandlerAst>(handlers, v); 1238 } 1239 { 1240 PyObjectRef orelse = getattr<PyObjectRef>(node, "orelse"); 1241 v->orelse = visitNodeList<Ast>(orelse, v); 1242 } 1243 { 1244 PyObjectRef finalbody = getattr<PyObjectRef>(node, "finalbody"); 1245 v->finally = visitNodeList<Ast>(finalbody, v); 1246 } 1247 result = v; 1248 } 1249 #endif 1250 else { 1251 qWarning() << "Unsupported _stmt AST type: " << PyUnicodeObjectToQString(PyObject_Str(node)); 1252 Q_ASSERT(false); 1253 } 1254 1255 if ( ! result ) return nullptr; 1256 if ( ! ranges_copied ) { 1257 result->startCol = getattr<int>(node, "col_offset"); 1258 result->endCol = result->endCol; 1259 result->startLine = tline(getattr<int>(node, "lineno")); 1260 result->endLine = result->startLine; 1261 result->hasUsefulRangeInformation = true; 1262 } else { 1263 result->hasUsefulRangeInformation = true; 1264 } 1265 updateRanges(result); 1266 return result; 1267 } 1268 1269 Ast* AstTransformer::visitKeywordNode(PyObject* node, Ast* parent) 1270 { 1271 if ( !node || node == Py_None ) return nullptr; 1272 // qDebug() << "visit keyword: " << PyUnicodeObjectToQString(PyObject_Str(node)); 1273 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_keyword)); 1274 KeywordAst* v = new KeywordAst(parent); 1275 QString arg = getattr<QString>(node, "arg"); 1276 v->argumentName = arg.size() ? new Python::Identifier(arg) : nullptr; 1277 { 1278 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 1279 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 1280 } 1281 return v; 1282 } 1283 1284 1285 Ast* AstTransformer::visitWithItemNode(PyObject* node, Ast* parent) 1286 { 1287 if ( !node || node == Py_None ) return nullptr; 1288 // qDebug() << "visit with item: " << PyUnicodeObjectToQString(PyObject_Str(node)); 1289 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_withitem)); 1290 WithItemAst* v = new WithItemAst(parent); 1291 { 1292 PyObjectRef context_expr = getattr<PyObjectRef>(node, "context_expr"); 1293 v->contextExpression = static_cast<ExpressionAst*>(visitExprNode(context_expr, v)); 1294 } 1295 { 1296 PyObjectRef optional_vars = getattr<PyObjectRef>(node, "optional_vars"); 1297 v->optionalVars = static_cast<ExpressionAst*>(visitExprNode(optional_vars, v)); 1298 } 1299 return v; 1300 } 1301 1302 #if PYTHON_VERSION >= QT_VERSION_CHECK(3, 10, 0) 1303 Ast* AstTransformer::visitMatchCaseNode(PyObject* node, Ast* parent) 1304 { 1305 if ( !node || node == Py_None ) return nullptr; 1306 // qDebug() << "visit match case: " << PyUnicodeObjectToQString(PyObject_Str(node)); 1307 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_match_case)); 1308 MatchCaseAst* v = new MatchCaseAst(parent); 1309 { 1310 PyObjectRef pattern = getattr<PyObjectRef>(node, "pattern"); 1311 v->pattern = static_cast<PatternAst*>(visitPatternNode(pattern, v)); 1312 } 1313 { 1314 PyObjectRef guard = getattr<PyObjectRef>(node, "guard"); 1315 v->guard = static_cast<ExpressionAst*>(visitExprNode(guard, v)); 1316 } 1317 { 1318 PyObjectRef body = getattr<PyObjectRef>(node, "body"); 1319 v->body = visitNodeList<Ast>(body, v); 1320 } 1321 return v; 1322 } 1323 Ast* AstTransformer::visitPatternNode(PyObject* node, Ast* parent) 1324 { 1325 if ( !node || node == Py_None ) return nullptr; 1326 // qDebug() << "visit pattern: " << PyUnicodeObjectToQString(PyObject_Str(node)); 1327 Q_ASSERT(PyObject_IsInstance(node, grammar.ast_pattern)); 1328 Ast* result = nullptr; 1329 if (PyObject_IsInstance(node, grammar.ast_MatchValue)) { 1330 MatchValueAst* v = new MatchValueAst(parent); 1331 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 1332 v->value = static_cast<ExpressionAst*>(visitExprNode(value, v)); 1333 result = v; 1334 } 1335 else if (PyObject_IsInstance(node, grammar.ast_MatchSingleton)) { 1336 MatchSingletonAst* v = new MatchSingletonAst(parent); 1337 { 1338 PyObjectRef value = getattr<PyObjectRef>(node, "value"); 1339 if (value == Py_None) 1340 v->value = NameConstantAst::None; 1341 else if (value == Py_False) 1342 v->value = NameConstantAst::False; 1343 else 1344 v->value = NameConstantAst::True; 1345 } 1346 result = v; 1347 } 1348 else if (PyObject_IsInstance(node, grammar.ast_MatchSequence)) { 1349 MatchSequenceAst* v = new MatchSequenceAst(parent); 1350 PyObjectRef patterns = getattr<PyObjectRef>(node, "patterns"); 1351 v->patterns = visitNodeList<PatternAst>(patterns, v); 1352 result = v; 1353 } 1354 else if (PyObject_IsInstance(node, grammar.ast_MatchMapping)) { 1355 MatchMappingAst* v = new MatchMappingAst(parent); 1356 { 1357 PyObjectRef keys = getattr<PyObjectRef>(node, "keys"); 1358 v->keys = visitNodeList<ExpressionAst>(keys, v); 1359 } 1360 { 1361 QString rest = getattr<QString>(node, "rest"); 1362 v->rest = rest.size() ? new Python::Identifier(rest) : nullptr; 1363 } 1364 { 1365 PyObjectRef patterns = getattr<PyObjectRef>(node, "patterns"); 1366 v->patterns = visitNodeList<PatternAst>(patterns, v); 1367 } 1368 result = v; 1369 } 1370 else if (PyObject_IsInstance(node, grammar.ast_MatchClass)) { 1371 MatchClassAst* v = new MatchClassAst(parent); 1372 { 1373 PyObjectRef cls = getattr<PyObjectRef>(node, "cls"); 1374 v->cls = static_cast<ExpressionAst*>(visitExprNode(cls, v)); 1375 } 1376 { 1377 PyObjectRef patterns = getattr<PyObjectRef>(node, "patterns"); 1378 v->patterns = visitNodeList<PatternAst>(patterns, v); 1379 } 1380 { 1381 QString kwd_attrs = getattr<QString>(node, "kwd_attrs"); 1382 v->kwdAttrs = kwd_attrs.size() ? new Python::Identifier(kwd_attrs) : nullptr; 1383 } 1384 { 1385 PyObjectRef kwd_patterns = getattr<PyObjectRef>(node, "kwd_patterns"); 1386 v->kwdPatterns = visitNodeList<PatternAst>(kwd_patterns, v); 1387 } 1388 result = v; 1389 } 1390 else if (PyObject_IsInstance(node, grammar.ast_MatchStar)) { 1391 MatchStarAst* v = new MatchStarAst(parent); 1392 QString name = getattr<QString>(node, "name"); 1393 v->name = name.size() ? new Python::Identifier(name) : nullptr; 1394 result = v; 1395 } 1396 else if (PyObject_IsInstance(node, grammar.ast_MatchAs)) { 1397 MatchAsAst* v = new MatchAsAst(parent); 1398 { 1399 PyObjectRef pattern = getattr<PyObjectRef>(node, "pattern"); 1400 v->pattern = static_cast<PatternAst*>(visitPatternNode(pattern, v)); 1401 } 1402 { 1403 QString name = getattr<QString>(node, "name"); 1404 v->name = name.size() ? new Python::Identifier(name) : nullptr; 1405 if (v->name) { 1406 v->name->startLine = tline(getattr<int>(node, "end_lineno")); 1407 v->name->endCol = getattr<int>(node, "end_col_offset") - 1; 1408 v->name->endLine = v->name->startLine; 1409 v->name->startCol = v->name->endCol - name.size() + 1; 1410 v->copyRange(v->name); 1411 } 1412 } 1413 result = v; 1414 } 1415 else if (PyObject_IsInstance(node, grammar.ast_MatchOr)) { 1416 MatchOrAst* v = new MatchOrAst(parent); 1417 { 1418 PyObjectRef patterns = getattr<PyObjectRef>(node, "patterns"); 1419 v->patterns = visitNodeList<PatternAst>(patterns, v); 1420 } 1421 result = v; 1422 } 1423 else { 1424 qWarning() << "Unsupported pattern AST type: " << PyUnicodeObjectToQString(PyObject_Str(node)); 1425 Q_ASSERT(false); 1426 } 1427 if ( ! result ) return nullptr; 1428 updateRanges(result); 1429 return result; 1430 } 1431 #endif 1432 1433 void AstTransformer::updateRanges(Ast* result) 1434 { 1435 // Walk through the tree and set proper end columns and lines, as the python parser sadly does not do this for us 1436 if ( result->hasUsefulRangeInformation ) { 1437 Ast* parent = result->parent; 1438 while ( parent ) { 1439 if ( parent->endLine < result->endLine ) { 1440 parent->endLine = result->endLine; 1441 parent->endCol = result->endCol; 1442 } 1443 if ( ! parent->hasUsefulRangeInformation && parent->startLine == -99999 ) { 1444 parent->startLine = result->startLine; 1445 parent->startCol = result->startCol; 1446 } 1447 parent = parent->parent; 1448 } 1449 } 1450 1451 if ( result && result->astType == Ast::NameAstType ) { 1452 NameAst* r = static_cast<NameAst*>(result); 1453 r->startCol = r->identifier->startCol; 1454 r->endCol = r->identifier->endCol; 1455 r->startLine = r->identifier->startLine; 1456 r->endLine = r->identifier->endLine; 1457 } 1458 } 1459 1460 } // end namespace Python