/***************************************************************************
* This file is part of KDevelop *
* Copyright 2007 Andreas Pakulat *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "astbuilder.h"
#include
#include "pythonparser.h"
#include "ast.h"
#include
#include
#include
#include "kurl.h"
#include
#include
#include
#include
#include
#include "parserConfig.h"
namespace Python
{
CodeAst* AstBuilder::parse(KUrl filename)
{
CodeAst* ast = parseXmlAst(getXmlForFile(filename));
return ast;
}
QString AstBuilder::getXmlForFile(KUrl filename)
{
QProcess* parser = new QProcess();
// we call a python script to parse the code for us. It returns an XML string with the AST
// kDebug() << QDir::current();
kDebug() << "+++ Starting parser for file " << filename.path();
parser->start("/usr/bin/env", QStringList() << "python" << QString(INSTALL_PATH) + QString("/pythonpythonparser.py") << filename.path());
parser->waitForFinished();
kDebug() << " ** Reading results...";
// TODO this is not clean
if ( parser->exitStatus() != QProcess::NormalExit ) {
kError() << "Error parsing file: " << parser->errorString();
return "";
}
QString result = parser->readAllStandardOutput();
kDebug() << " ** XML for " << filename << ": length" << result.length();
if ( ! result.length() ) {
result = parser->readAllStandardError();
result.split(":");
int lineno = result[0].toAscii();
int colno = result[1].toAscii();
KDevelop::ProblemPointer p(new KDevelop::Problem());
p->setFinalLocation(KDevelop::DocumentRange(KDevelop::IndexedString(filename), KDevelop::SimpleRange(lineno, colno, lineno, colno + 1)));
p->setSource(KDevelop::ProblemData::Disk);
p->setDescription(result);
kWarning() << "Parse Error: " << result;
return "0";
}
delete parser;
return result;
}
CodeAst* AstBuilder::parseXmlAst(QString xml)
{
Q_ASSERT(xml.length());
if ( xml == "0" ) {
return 0;
}
QXmlStreamReader* xmlast = new QXmlStreamReader();
xmlast->addData(xml);
m_nodeMap.clear();
parseXmlAstNode(xmlast, QXmlStreamReader::Invalid);
populateAst();
CodeAst* codeAst = dynamic_cast(m_currentNode);
Q_ASSERT(codeAst);
return codeAst;
}
void AstBuilder::parseXmlAstNode(QXmlStreamReader* xmlast, QXmlStreamReader::TokenType token = QXmlStreamReader::Invalid) {
bool nodeAdded = false;
while ( ! xmlast->atEnd() && ! xmlast->hasError() ) {
// Advance to the next (first) token
QXmlStreamReader::TokenType token = xmlast->readNext();
// Store everything we need later into local variables
QString currentElementName = xmlast->name().toString();
QString currentElementText = xmlast->text().toString();
QList currentElementAttributes = xmlast->attributes().toList();
// We ignore startDocument and EndDocument
if ( token == QXmlStreamReader::StartDocument || token == QXmlStreamReader::EndDocument ) {
continue;
}
// We recursively continue parsing if we find another element
else if ( token == QXmlStreamReader::StartElement ) {
// Here we can now assemble an actual node with the attributes extracted above
// Skip the document root element
if ( currentElementName == "pythonast" ) {
parseXmlAstNode(xmlast, token);
continue;
}
// kDebug() << "Token: " << token << "; " << "Name: " << currentElementName << "; Text: " << currentElementText;
// for ( int i=0; i& attributes)
{
Ast* ast;
QMap attributeDict;
for ( int i=0; i T* AstBuilder::resolveNode(const QString& identifier)
{
if ( ! identifier.length() ) return 0;
int id = identifier.toInt();
Ast* found = m_nodeMap.value(id);
T* ret = dynamic_cast(found);
Q_ASSERT(found || ! ret);
return found ? ret : 0;
}
template QList AstBuilder::resolveNodeList(const QString& commaSeperatedIdentifiers)
{
QList items;
items.clear();
QStringList identifiers = commaSeperatedIdentifiers.split(",");
T* found;
for ( int i=0; i(identifiers.at(i));
if ( found ) items << found;
}
return items;
}
Identifier* AstBuilder::createIdentifier(const QString& name, Ast* range)
{
Identifier* ident = new Identifier(name);
ident->startCol = range->startCol;
ident->endCol = range->startCol + name.length() - 1;
ident->startLine = range->startLine;
ident->endLine = range->endLine;
return ident;
}
ExpressionAst::Context AstBuilder::resolveContext(const QString& identifier)
{
int id = identifier.toInt();
if ( ! id ) return ExpressionAst::Invalid;
return m_contextNodeMap.value(id);
}
Ast::BooleanOperationTypes AstBuilder::resolveBooleanOperator(const QString& identifier)
{
int id = identifier.toInt();
if ( ! id ) return Ast::BooleanInvalidOperation;
return m_boolOpNodeMap.value(id);
}
Ast::OperatorTypes AstBuilder::resolveOperator(const QString& identifier)
{
int id = identifier.toInt();
if ( ! id ) return Ast::OperatorInvalid;
return m_opNodeMap.value(id);
}
Ast::UnaryOperatorTypes AstBuilder::resolveUnaryOperator(const QString& identifier)
{
int id = identifier.toInt();
if ( ! id ) return Ast::UnaryOperatorInvalid;
return m_unaryOpNodeMap.value(id);
}
Ast::ComparisonOperatorTypes AstBuilder::resolveComparisonOperator(const QString& identifier)
{
int id = identifier.toInt();
if ( ! id ) return Ast::ComparisonOperatorInvalid;
return m_compOpNodeMap.value(id);
}
QList< Ast::ComparisonOperatorTypes > AstBuilder::resolveComparisonOperatorList(const QString& identifiers)
{
QList<:comparisonoperatortypes> items;
QList ids = identifiers.split(",");
for ( int i=0; i < ids.length(); i++ ) {
items << resolveComparisonOperator(ids.at(i));
}
return items;
}
ExecAst* AstBuilder::populateExecAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ExecAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNode(currentAttributes.value("NR_body"));
currentNode->locals = resolveNode(currentAttributes.value("NR_locals"));
currentNode->globals = resolveNode(currentAttributes.value("NR_globals"));
return currentNode;
}
NameAst* AstBuilder::populateNameAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
NameAst* currentNode = dynamic_cast(ast);
currentNode->context = resolveContext(currentAttributes.value("NR_ctx"));
currentNode->identifier = createIdentifier(currentAttributes.value("id"), currentNode);
// kDebug() << "Processing NameAst" << currentNode->identifier->value;
return currentNode;
}
ClassDefinitionAst* AstBuilder::populateClassDefinitonAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ClassDefinitionAst* currentNode = dynamic_cast(ast);
currentNode->baseClasses = resolveNodeList(currentAttributes.value("NRLST_bases"));
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
currentNode->decorators = resolveNodeList(currentAttributes.value("NRLST_decorator_list"));
currentNode->name = createIdentifier(currentAttributes.value("name"), currentNode);
currentNode->name->startCol += 6; // TODO fix this! ;D
currentNode->name->endCol += 6;
return currentNode;
}
FunctionDefinitionAst* AstBuilder::populateFunctionDefinitionAst(Ast* ast, const stringDictionary& currentAttributes)
{
FunctionDefinitionAst* currentNode = dynamic_cast(ast);
currentNode->arguments = resolveNode(currentAttributes.value("NR_args"));
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
currentNode->decorators = resolveNodeList(currentAttributes.value("NRLST_decorator_list"));
currentNode->name = createIdentifier(currentAttributes.value("name"), currentNode);
currentNode->name->startCol += 4; // TODO fix this! ;D
currentNode->name->endCol += 4;
return currentNode;
}
AssignmentAst* AstBuilder::populateAssignmentAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
AssignmentAst* currentNode = dynamic_cast(ast);
currentNode->value = resolveNode(currentAttributes.value("NR_value"));
currentNode->targets = resolveNodeList(currentAttributes.value("NRLST_targets"));
return currentNode;
}
CodeAst* AstBuilder::populateCodeAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
CodeAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
return currentNode;
}
DeleteAst* AstBuilder::populateDeleteAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
DeleteAst* currentNode = dynamic_cast(ast);
currentNode->targets = resolveNodeList(currentAttributes.value("NRLST_targets"));
return currentNode;
}
ForAst* AstBuilder::populateForAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ForAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
currentNode->orelse = resolveNodeList(currentAttributes.value("NRLST_orelse"));
currentNode->iterator = resolveNode(currentAttributes.value("NR_iter"));
currentNode->target = resolveNode(currentAttributes.value("NR_target"));
return currentNode;
}
PrintAst* AstBuilder::populatePrintAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
PrintAst* currentNode = dynamic_cast(ast);
currentNode->destination = resolveNode(currentAttributes.value("NR_dest"));
currentNode->newline = currentAttributes.value("nl") == "True" ? true : false;
currentNode->values = resolveNodeList(currentAttributes.value("NRLST_values"));
return currentNode;
}
ReturnAst* AstBuilder::populateReturnAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ReturnAst* currentNode = dynamic_cast(ast);
currentNode->value = resolveNode(currentAttributes.value("NR_value"));
return currentNode;
}
IfAst* AstBuilder::populateIfAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
IfAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
currentNode->condition = resolveNode(currentAttributes.value("NR_test"));
currentNode->orelse = resolveNodeList(currentAttributes.value("NRLST_orelse"));
return currentNode;
}
BooleanOperationAst* AstBuilder::populateBooleanOperationAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
BooleanOperationAst* currentNode = dynamic_cast(ast);
currentNode->values = resolveNodeList(currentAttributes.value("NRLST_values"));
currentNode->type = resolveBooleanOperator(currentAttributes.value("NR_op"));
return currentNode;
}
CallAst* AstBuilder::populateCallAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
CallAst* currentNode = dynamic_cast(ast);
currentNode->arguments = resolveNodeList(currentAttributes.value("NRLST_args"));
currentNode->function = resolveNode(currentAttributes.value("NR_func"));
currentNode->keywordArguments = resolveNode(currentAttributes.value("NR_kwargs"));
currentNode->keywords = resolveNodeList(currentAttributes.value("NRLST_keywords"));
currentNode->starArguments = resolveNode(currentAttributes.value("NR_starargs"));
return currentNode;
}
LambdaAst* AstBuilder::populateLambdaAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
LambdaAst* currentNode = dynamic_cast(ast);
currentNode->arguments = resolveNode(currentAttributes.value("NR_args"));
currentNode->body = resolveNode(currentAttributes.value("NR_body"));
return currentNode;
}
WhileAst* AstBuilder::populateWhileAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
WhileAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
currentNode->orelse = resolveNodeList(currentAttributes.value("NRLST_orelse"));
currentNode->condition = resolveNode(currentAttributes.value("NR_test"));
return currentNode;
}
DictAst* AstBuilder::populateDictAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
DictAst* currentNode = dynamic_cast(ast);
currentNode->keys = resolveNodeList(currentAttributes.value("NRLST_keys"));
currentNode->values = resolveNodeList(currentAttributes.value("NRLST_values"));
return currentNode;
}
ListAst* AstBuilder::populateListAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ListAst* currentNode = dynamic_cast(ast);
currentNode->elements = resolveNodeList(currentAttributes.value("NRLST_elts"));
currentNode->context = resolveContext(currentAttributes.value("NR_ctx"));
return currentNode;
}
TupleAst* AstBuilder::populateTupleAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
TupleAst* currentNode = dynamic_cast(ast);
currentNode->context = resolveContext(currentAttributes.value("NR_ctx"));
currentNode->elements = resolveNodeList(currentAttributes.value("NRLST_elts"));
return currentNode;
}
AugmentedAssignmentAst* AstBuilder::populateAugmentedAssignmentAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
AugmentedAssignmentAst* currentNode = dynamic_cast(ast);
currentNode->op = resolveOperator(currentAttributes.value("NR_op"));
currentNode->target = resolveNode(currentAttributes.value("NR_target"));
currentNode->value = resolveNode(currentAttributes.value("NR_value"));
return currentNode;
}
RaiseAst* AstBuilder::populateRaiseAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
RaiseAst* currentNode = dynamic_cast(ast);
currentNode->type = resolveNode(currentAttributes.value("NR_type"));
return currentNode;
}
TryExceptAst* AstBuilder::populateTryExceptAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
TryExceptAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
currentNode->handlers = resolveNodeList(currentAttributes.value("NRLST_handlers"));
currentNode->orelse = resolveNodeList(currentAttributes.value("NRLST_orelse"));
return currentNode;
}
TryFinallyAst* AstBuilder::populateTryFinallyAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
TryFinallyAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
currentNode->finalbody = resolveNodeList(currentAttributes.value("NRLST_finalbody"));
return currentNode;
}
AssertionAst* AstBuilder::populateAssertionAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
AssertionAst* currentNode = dynamic_cast(ast);
currentNode->condition = resolveNode(currentAttributes.value("NR_test"));
currentNode->message = resolveNode(currentAttributes.value("NR_msg"));
return currentNode;
}
BinaryOperationAst* AstBuilder::populateBinaryOperationAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
BinaryOperationAst* currentNode = dynamic_cast(ast);
currentNode->rhs = resolveNode(currentAttributes.value("NR_right"));
currentNode->lhs = resolveNode(currentAttributes.value("NR_left"));
currentNode->type = resolveOperator(currentAttributes.value("NR_op"));
return currentNode;
}
ImportAst* AstBuilder::populateImportAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ImportAst* currentNode = dynamic_cast(ast);
currentNode->names = resolveNodeList(currentAttributes.value("NRLST_names"));
return currentNode;
}
ImportFromAst* AstBuilder::populateImportFromAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ImportFromAst* currentNode = dynamic_cast(ast);
currentNode->level = currentAttributes.value("level").toInt();
currentNode->module = createIdentifier(currentAttributes.value("module"), currentNode);
currentNode->names = resolveNodeList(currentAttributes.value("NRLST_names"));
return currentNode;
}
AliasAst* AstBuilder::populateAliasAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
AliasAst* currentNode = dynamic_cast(ast);
currentNode->asName = resolveNode(currentAttributes.value("NR_asname"));
currentNode->name = createIdentifier(currentAttributes.value("name"), currentNode);
return currentNode;
}
GlobalAst* AstBuilder::populateGlobalAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
GlobalAst* currentNode = dynamic_cast(ast);
// currentNode->names = resolveNodeList(currentAttributes.value("NRLST_names")); // TODO the parser does not write this correctly! also, need to fix resolve
return currentNode;
}
UnaryOperationAst* AstBuilder::populateUnaryOperationAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
UnaryOperationAst* currentNode = dynamic_cast(ast);
currentNode->operand = resolveNode(currentAttributes.value("NR_operand"));
currentNode->type = resolveUnaryOperator(currentAttributes.value("NR_op"));
return currentNode;
}
IfExpressionAst* AstBuilder::populateIfExpressionAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
IfExpressionAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNode(currentAttributes.value("NR_body"));
currentNode->orelse = resolveNode(currentAttributes.value("NR_orelse"));
currentNode->condition = resolveNode(currentAttributes.value("NR_test"));
return currentNode;
}
ListComprehensionAst* AstBuilder::populateListComprehensionAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ListComprehensionAst* currentNode = dynamic_cast(ast);
currentNode->generators = resolveNodeList(currentAttributes.value("NRLST_generators"));
currentNode->element = resolveNode(currentAttributes.value("NR_elt"));
return currentNode;
}
WithAst* AstBuilder::populateWithAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
WithAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
currentNode->contextExpression = resolveNode(currentAttributes.value("NR_context_expr"));
currentNode->optionalVars = resolveNode(currentAttributes.value("NR_optional_vars"));
return currentNode;
}
ComprehensionAst* AstBuilder::populateComprehensionAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ComprehensionAst* currentNode = dynamic_cast(ast);
currentNode->conditions = resolveNodeList(currentAttributes.value("NRLST_ifs"));
currentNode->iterator = resolveNode(currentAttributes.value("NR_iter"));
currentNode->target = resolveNode(currentAttributes.value("NR_target"));
return currentNode;
}
CompareAst* AstBuilder::populateCompareAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
CompareAst* currentNode = dynamic_cast(ast);
currentNode->comparands = resolveNodeList(currentAttributes.value("NRLST_comparators"));
currentNode->operators = resolveComparisonOperatorList(currentAttributes.value("NRLST_ops"));
currentNode->leftmostElement = resolveNode(currentAttributes.value("NR_left"));
return currentNode;
}
NumberAst* AstBuilder::populateNumberAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
NumberAst* currentNode = dynamic_cast(ast);
currentNode->value = currentAttributes.value("n"); // save this as a QString to aviod problems with python number formats like 3j+2 (complex), 3L, 3.35, etc.
return currentNode;
}
StringAst* AstBuilder::populateStringAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
StringAst* currentNode = dynamic_cast(ast);
currentNode->value = currentAttributes.value("s");
return currentNode;
}
AttributeAst* AstBuilder::populateAttributeAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
AttributeAst* currentNode = dynamic_cast(ast);
currentNode->value = resolveNode(currentAttributes.value("NR_value"));
currentNode->attribute = createIdentifier(currentAttributes.value("attr"), currentNode);
currentNode->context = resolveContext(currentAttributes.value("NR_ctx"));
return currentNode;
}
SubscriptAst* AstBuilder::populateSubscriptAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
SubscriptAst* currentNode = dynamic_cast(ast);
currentNode->context = resolveContext("NR_ctx");
currentNode->slice = resolveNode(currentAttributes.value("NR_slice"));
currentNode->value = resolveNode(currentAttributes.value("NR_value"));
return currentNode;
}
SliceAst* AstBuilder::populateSliceAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
SliceAst* currentNode = dynamic_cast(ast);
currentNode->lower = resolveNode(currentAttributes.value("NR_lower"));
currentNode->upper = resolveNode(currentAttributes.value("NR_upper"));
currentNode->step = resolveNode(currentAttributes.value("NR_step"));
return currentNode;
}
ArgumentsAst* AstBuilder::populateArgumentsAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ArgumentsAst* currentNode = dynamic_cast(ast);
currentNode->arguments = resolveNodeList(currentAttributes.value("NRLST_args"));
currentNode->defaultValues = resolveNodeList(currentAttributes.value("NRLST_defaults"));
currentNode->kwarg = createIdentifier(currentAttributes.value("kwarg"), currentNode);
currentNode->vararg = createIdentifier(currentAttributes.value("paramstar"), currentNode);
return currentNode;
}
ExceptionHandlerAst* AstBuilder::populateExceptionHandlerAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
ExceptionHandlerAst* currentNode = dynamic_cast(ast);
currentNode->body = resolveNodeList(currentAttributes.value("NRLST_body"));
currentNode->name = resolveNode(currentAttributes.value("NR_name"));
currentNode->type = resolveNode(currentAttributes.value("NR_type"));
return currentNode;
}
IndexAst* AstBuilder::populateIndexAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
IndexAst* currentNode = dynamic_cast(ast);
currentNode->value = resolveNode(currentAttributes.value("NR_value"));
return currentNode;
}
KeywordAst* AstBuilder::populateKeywordAst(Ast* ast, const Python::stringDictionary& currentAttributes)
{
KeywordAst* currentNode = dynamic_cast(ast);
currentNode->argumentName = createIdentifier(currentAttributes.value("arg"), currentNode);
currentNode->value = resolveNode(currentAttributes.value("NR_value"));
return currentNode;
}
void AstBuilder::populateAst()
{
Ast* currentAbstractNode;
stringDictionary currentAttributes;
QMapIterator i(m_nodeMap);
while ( i.hasNext() ) {
i.next();
currentAbstractNode = i.value();
currentAttributes = m_attributeStore.value(i.key());
// kDebug() << "Processing AST node ID " << i.key();
// kDebug() << "Amount of attributes: " << currentAttributes.size();
stringDictionary::const_iterator i = currentAttributes.begin();
// while ( i != currentAttributes.end() ) {
// kDebug() << i.key() << i.value();
// ++i;
// }
if ( currentAttributes.value("lineno").length() > 0 && currentAttributes.value("col_offset").length() > 0 )
currentAbstractNode->hasUsefulRangeInformation = true;
else currentAbstractNode->hasUsefulRangeInformation = false;
int startLine = currentAttributes.value("lineno").toInt() - 1; // start = 0 <> start = 1
currentAbstractNode->startLine = startLine;
currentAbstractNode->endLine = startLine;
int startCol = currentAttributes.value("col_offset").toInt();
currentAbstractNode->startCol = startCol;
currentAbstractNode->endCol = startCol; // this is justified if necessary (only an AST with an actual value or identifier will know the true range)
switch ( currentAbstractNode->astType ) {
case Ast::CodeAstType: currentAbstractNode = populateCodeAst(currentAbstractNode, currentAttributes); break;
case Ast::FunctionDefinitionAstType: currentAbstractNode = populateFunctionDefinitionAst(currentAbstractNode, currentAttributes); break;
case Ast::ClassDefinitionAstType: currentAbstractNode = populateClassDefinitonAst(currentAbstractNode, currentAttributes); break;
case Ast::ReturnAstType: currentAbstractNode = populateReturnAst(currentAbstractNode, currentAttributes); break;
case Ast::DeleteAstType: currentAbstractNode = populateDeleteAst(currentAbstractNode, currentAttributes); break;
case Ast::AssignmentAstType: currentAbstractNode = populateAssignmentAst(currentAbstractNode, currentAttributes); break;
case Ast::AugmentedAssignmentAstType: currentAbstractNode = populateAugmentedAssignmentAst(currentAbstractNode, currentAttributes); break;
case Ast::ForAstType: currentAbstractNode = populateForAst(currentAbstractNode, currentAttributes); break;
case Ast::WhileAstType: currentAbstractNode = populateWhileAst(currentAbstractNode, currentAttributes); break;
case Ast::IfAstType: currentAbstractNode = populateIfAst(currentAbstractNode, currentAttributes); break;
case Ast::WithAstType: currentAbstractNode = populateWithAst(currentAbstractNode, currentAttributes); break;
case Ast::RaiseAstType: currentAbstractNode = populateRaiseAst(currentAbstractNode, currentAttributes); break;
case Ast::TryExceptAstType: currentAbstractNode = populateTryExceptAst(currentAbstractNode, currentAttributes); break;
case Ast::TryFinallyAstType: currentAbstractNode = populateTryFinallyAst(currentAbstractNode, currentAttributes); break;
case Ast::AssertionAstType: currentAbstractNode = populateAssertionAst(currentAbstractNode, currentAttributes); break;
case Ast::ImportAstType: currentAbstractNode = populateImportAst(currentAbstractNode, currentAttributes); break;
case Ast::ImportFromAstType: currentAbstractNode = populateImportFromAst(currentAbstractNode, currentAttributes); break;
// case Ast::ExecAstType: break; // TODO support this? or better not? :]
case Ast::GlobalAstType: currentAbstractNode = populateGlobalAst(currentAbstractNode, currentAttributes); break;
case Ast::BreakAstType: break; // ok
case Ast::ContinueAstType: break; // ok
case Ast::PrintAstType: currentAbstractNode = populatePrintAst(currentAbstractNode, currentAttributes); break;
case Ast::PassAstType: break; // ok
case Ast::BooleanOperationAstType: currentAbstractNode = populateBooleanOperationAst(currentAbstractNode, currentAttributes); break;
case Ast::BinaryOperationAstType: currentAbstractNode = populateBinaryOperationAst(currentAbstractNode, currentAttributes); break;
case Ast::UnaryOperationAstType: currentAbstractNode = populateUnaryOperationAst(currentAbstractNode, currentAttributes); break;
case Ast::LambdaAstType: currentAbstractNode = populateLambdaAst(currentAbstractNode, currentAttributes); break;
case Ast::IfExpressionAstType: currentAbstractNode = populateIfExpressionAst(currentAbstractNode, currentAttributes); break;
case Ast::DictAstType: currentAbstractNode = populateDictAst(currentAbstractNode, currentAttributes); break;
// case Ast::SetAstType: break; // TODO support this (read about sets)
case Ast::ListComprehensionAstType: currentAbstractNode = populateListComprehensionAst(currentAbstractNode, currentAttributes); break;
// case Ast::SetComprehensionAstType: break; // TODO support this
// case Ast::DictionaryComprehensionAstType: break; // TODO fix this for python 2.7+
// case Ast::GeneratorExpressionAstType: break; // TODO read about this
case Ast::CompareAstType: currentAbstractNode = populateCompareAst(currentAbstractNode, currentAttributes); break;
// case Ast::ReprAstType: break; // TODO support this
case Ast::NumberAstType: currentAbstractNode = populateNumberAst(currentAbstractNode, currentAttributes); break;
case Ast::StringAstType: currentAbstractNode = populateStringAst(currentAbstractNode, currentAttributes); break;
// case Ast::YieldAstType: break; // TODO TODO
case Ast::NameAstType: currentAbstractNode = populateNameAst(currentAbstractNode, currentAttributes); break;
case Ast::CallAstType: currentAbstractNode = populateCallAst(currentAbstractNode, currentAttributes); break;
case Ast::AttributeAstType: currentAbstractNode = populateAttributeAst(currentAbstractNode, currentAttributes); break;
case Ast::SubscriptAstType: currentAbstractNode = populateSubscriptAst(currentAbstractNode, currentAttributes); break;
case Ast::ListAstType: currentAbstractNode = populateListAst(currentAbstractNode, currentAttributes); break;
case Ast::TupleAstType: currentAbstractNode = populateTupleAst(currentAbstractNode, currentAttributes); break;
// case Ast::EllipsisAstType: break; // TODO TODO
case Ast::SliceAstType: currentAbstractNode = populateSliceAst(currentAbstractNode, currentAttributes); break;
// case Ast::ExtendedSliceAstType: break; // TODO TODO
case Ast::IndexAstType: currentAbstractNode = populateIndexAst(currentAbstractNode, currentAttributes); break;
case Ast::ArgumentsAstType: currentAbstractNode = populateArgumentsAst(currentAbstractNode, currentAttributes); break;
case Ast::KeywordAstType: currentAbstractNode = populateKeywordAst(currentAbstractNode, currentAttributes); break;
case Ast::ComprehensionAstType: currentAbstractNode = populateComprehensionAst(currentAbstractNode, currentAttributes); break;
case Ast::ExceptionHandlerAstType: currentAbstractNode = populateExceptionHandlerAst(currentAbstractNode, currentAttributes); break;
case Ast::AliasAstType: currentAbstractNode = populateAliasAst(currentAbstractNode, currentAttributes); break;
case Ast::ExpressionAstType: break; // ok
case Ast::StatementAstType: break; // ok
}
}
}
}