File indexing completed on 2024-05-19 15:46:43

0001 /*
0002     SPDX-FileCopyrightText: 2012 Milian Wolff <mail@milianw.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "debugvisitor.h"
0008 
0009 #include "parsesession.h"
0010 
0011 #include <qmljs/parser/qmljsast_p.h>
0012 
0013 using namespace KDevelop;
0014 
0015 QString DebugVisitor::stringForAstKind(int kind)
0016 {
0017     switch (kind) {
0018         case QmlJS::AST::Node::Kind_Undefined: return QStringLiteral("Undefined");
0019         case QmlJS::AST::Node::Kind_ArgumentList: return QStringLiteral("ArgumentList");
0020         case QmlJS::AST::Node::Kind_ArrayLiteral: return QStringLiteral("ArrayLiteral");
0021         case QmlJS::AST::Node::Kind_ArrayMemberExpression: return QStringLiteral("ArrayMemberExpression");
0022         case QmlJS::AST::Node::Kind_BinaryExpression: return QStringLiteral("BinaryExpression");
0023         case QmlJS::AST::Node::Kind_Block: return QStringLiteral("Block");
0024         case QmlJS::AST::Node::Kind_BreakStatement: return QStringLiteral("BreakStatement");
0025         case QmlJS::AST::Node::Kind_CallExpression: return QStringLiteral("CallExpression");
0026         case QmlJS::AST::Node::Kind_CaseBlock: return QStringLiteral("CaseBlock");
0027         case QmlJS::AST::Node::Kind_CaseClause: return QStringLiteral("CaseClause");
0028         case QmlJS::AST::Node::Kind_CaseClauses: return QStringLiteral("CaseClauses");
0029         case QmlJS::AST::Node::Kind_Catch: return QStringLiteral("Catch");
0030         case QmlJS::AST::Node::Kind_ConditionalExpression: return QStringLiteral("ConditionalExpression");
0031         case QmlJS::AST::Node::Kind_ContinueStatement: return QStringLiteral("ContinueStatement");
0032         case QmlJS::AST::Node::Kind_DebuggerStatement: return QStringLiteral("DebuggerStatement");
0033         case QmlJS::AST::Node::Kind_DefaultClause: return QStringLiteral("DefaultClause");
0034         case QmlJS::AST::Node::Kind_DeleteExpression: return QStringLiteral("DeleteExpression");
0035         case QmlJS::AST::Node::Kind_DoWhileStatement: return QStringLiteral("DoWhileStatement");
0036         case QmlJS::AST::Node::Kind_ElementList: return QStringLiteral("ElementList");
0037         case QmlJS::AST::Node::Kind_Elision: return QStringLiteral("Elision");
0038         case QmlJS::AST::Node::Kind_EmptyStatement: return QStringLiteral("EmptyStatement");
0039         case QmlJS::AST::Node::Kind_Expression: return QStringLiteral("Expression");
0040         case QmlJS::AST::Node::Kind_ExpressionStatement: return QStringLiteral("ExpressionStatement");
0041         case QmlJS::AST::Node::Kind_FalseLiteral: return QStringLiteral("FalseLiteral");
0042         case QmlJS::AST::Node::Kind_FieldMemberExpression: return QStringLiteral("FieldMemberExpression");
0043         case QmlJS::AST::Node::Kind_Finally: return QStringLiteral("Finally");
0044         case QmlJS::AST::Node::Kind_ForEachStatement: return QStringLiteral("ForEachStatement");
0045         case QmlJS::AST::Node::Kind_ForStatement: return QStringLiteral("ForStatement");
0046         case QmlJS::AST::Node::Kind_FormalParameterList: return QStringLiteral("FormalParameterList");
0047         case QmlJS::AST::Node::Kind_FunctionBody: return QStringLiteral("FunctionBody");
0048         case QmlJS::AST::Node::Kind_FunctionDeclaration: return QStringLiteral("FunctionDeclaration");
0049         case QmlJS::AST::Node::Kind_FunctionExpression: return QStringLiteral("FunctionExpression");
0050         case QmlJS::AST::Node::Kind_FunctionSourceElement: return QStringLiteral("FunctionSourceElement");
0051         case QmlJS::AST::Node::Kind_IdentifierExpression: return QStringLiteral("IdentifierExpression");
0052         case QmlJS::AST::Node::Kind_IdentifierPropertyName: return QStringLiteral("IdentifierPropertyName");
0053         case QmlJS::AST::Node::Kind_IfStatement: return QStringLiteral("IfStatement");
0054         case QmlJS::AST::Node::Kind_LabelledStatement: return QStringLiteral("LabelledStatement");
0055         case QmlJS::AST::Node::Kind_LocalForEachStatement: return QStringLiteral("LocalForEachStatement");
0056         case QmlJS::AST::Node::Kind_LocalForStatement: return QStringLiteral("LocalForStatement");
0057         case QmlJS::AST::Node::Kind_NewExpression: return QStringLiteral("NewExpression");
0058         case QmlJS::AST::Node::Kind_NewMemberExpression: return QStringLiteral("NewMemberExpression");
0059         case QmlJS::AST::Node::Kind_NotExpression: return QStringLiteral("NotExpression");
0060         case QmlJS::AST::Node::Kind_NullExpression: return QStringLiteral("NullExpression");
0061         case QmlJS::AST::Node::Kind_NumericLiteral: return QStringLiteral("NumericLiteral");
0062         case QmlJS::AST::Node::Kind_NumericLiteralPropertyName: return QStringLiteral("NumericLiteralPropertyName");
0063         case QmlJS::AST::Node::Kind_ObjectLiteral: return QStringLiteral("ObjectLiteral");
0064         case QmlJS::AST::Node::Kind_PostDecrementExpression: return QStringLiteral("PostDecrementExpression");
0065         case QmlJS::AST::Node::Kind_PostIncrementExpression: return QStringLiteral("PostIncrementExpression");
0066         case QmlJS::AST::Node::Kind_PreDecrementExpression: return QStringLiteral("PreDecrementExpression");
0067         case QmlJS::AST::Node::Kind_PreIncrementExpression: return QStringLiteral("PreIncrementExpression");
0068         case QmlJS::AST::Node::Kind_Program: return QStringLiteral("Program");
0069         case QmlJS::AST::Node::Kind_PropertyAssignmentList: return QStringLiteral("PropertyAssignmentList");
0070         case QmlJS::AST::Node::Kind_PropertyGetterSetter: return QStringLiteral("PropertyGetterSetter");
0071         case QmlJS::AST::Node::Kind_PropertyName: return QStringLiteral("PropertyName");
0072         case QmlJS::AST::Node::Kind_PropertyNameAndValue: return QStringLiteral("PropertyNameAndValue");
0073         case QmlJS::AST::Node::Kind_RegExpLiteral: return QStringLiteral("RegExpLiteral");
0074         case QmlJS::AST::Node::Kind_ReturnStatement: return QStringLiteral("ReturnStatement");
0075         case QmlJS::AST::Node::Kind_SourceElement: return QStringLiteral("SourceElement");
0076         case QmlJS::AST::Node::Kind_SourceElements: return QStringLiteral("SourceElements");
0077         case QmlJS::AST::Node::Kind_StatementList: return QStringLiteral("StatementList");
0078         case QmlJS::AST::Node::Kind_StatementSourceElement: return QStringLiteral("StatementSourceElement");
0079         case QmlJS::AST::Node::Kind_StringLiteral: return QStringLiteral("StringLiteral");
0080         case QmlJS::AST::Node::Kind_StringLiteralPropertyName: return QStringLiteral("StringLiteralPropertyName");
0081         case QmlJS::AST::Node::Kind_SwitchStatement: return QStringLiteral("SwitchStatement");
0082         case QmlJS::AST::Node::Kind_ThisExpression: return QStringLiteral("ThisExpression");
0083         case QmlJS::AST::Node::Kind_ThrowStatement: return QStringLiteral("ThrowStatement");
0084         case QmlJS::AST::Node::Kind_TildeExpression: return QStringLiteral("TildeExpression");
0085         case QmlJS::AST::Node::Kind_TrueLiteral: return QStringLiteral("TrueLiteral");
0086         case QmlJS::AST::Node::Kind_TryStatement: return QStringLiteral("TryStatement");
0087         case QmlJS::AST::Node::Kind_TypeOfExpression: return QStringLiteral("TypeOfExpression");
0088         case QmlJS::AST::Node::Kind_UnaryMinusExpression: return QStringLiteral("UnaryMinusExpression");
0089         case QmlJS::AST::Node::Kind_UnaryPlusExpression: return QStringLiteral("UnaryPlusExpression");
0090         case QmlJS::AST::Node::Kind_VariableDeclaration: return QStringLiteral("VariableDeclaration");
0091         case QmlJS::AST::Node::Kind_VariableDeclarationList: return QStringLiteral("VariableDeclarationList");
0092         case QmlJS::AST::Node::Kind_VariableStatement: return QStringLiteral("VariableStatement");
0093         case QmlJS::AST::Node::Kind_VoidExpression: return QStringLiteral("VoidExpression");
0094         case QmlJS::AST::Node::Kind_WhileStatement: return QStringLiteral("WhileStatement");
0095         case QmlJS::AST::Node::Kind_WithStatement: return QStringLiteral("WithStatement");
0096         case QmlJS::AST::Node::Kind_NestedExpression: return QStringLiteral("NestedExpression");
0097         case QmlJS::AST::Node::Kind_UiArrayBinding: return QStringLiteral("UiArrayBinding");
0098         case QmlJS::AST::Node::Kind_UiImport: return QStringLiteral("UiImport");
0099         case QmlJS::AST::Node::Kind_UiObjectBinding: return QStringLiteral("UiObjectBinding");
0100         case QmlJS::AST::Node::Kind_UiObjectDefinition: return QStringLiteral("UiObjectDefinition");
0101         case QmlJS::AST::Node::Kind_UiObjectInitializer: return QStringLiteral("UiObjectInitializer");
0102         case QmlJS::AST::Node::Kind_UiObjectMemberList: return QStringLiteral("UiObjectMemberList");
0103         case QmlJS::AST::Node::Kind_UiArrayMemberList: return QStringLiteral("UiArrayMemberList");
0104         case QmlJS::AST::Node::Kind_UiPragma: return QStringLiteral("UiPragma");
0105         case QmlJS::AST::Node::Kind_UiProgram: return QStringLiteral("UiProgram");
0106         case QmlJS::AST::Node::Kind_UiParameterList: return QStringLiteral("UiParameterList");
0107         case QmlJS::AST::Node::Kind_UiPublicMember: return QStringLiteral("UiPublicMember");
0108         case QmlJS::AST::Node::Kind_UiQualifiedId: return QStringLiteral("UiQualifiedId");
0109         case QmlJS::AST::Node::Kind_UiQualifiedPragmaId: return QStringLiteral("UiQualifiedPragmaId");
0110         case QmlJS::AST::Node::Kind_UiScriptBinding: return QStringLiteral("UiScriptBinding");
0111         case QmlJS::AST::Node::Kind_UiSourceElement: return QStringLiteral("UiSourceElement");
0112         case QmlJS::AST::Node::Kind_UiHeaderItemList: return QStringLiteral("UiHeaderItemList");
0113     }
0114     return QStringLiteral("<unknown node kind>");
0115 }
0116 
0117 DebugVisitor::DebugVisitor(const ParseSession* session)
0118 : m_session(session)
0119 , m_depth(0)
0120 {
0121 }
0122 
0123 void DebugVisitor::startVisiting(QmlJS::AST::Node* node)
0124 {
0125     QmlJS::AST::Node::accept(node, this);
0126 }
0127 
0128 bool DebugVisitor::preVisit(QmlJS::AST::Node* node)
0129 {
0130     printNode(node, Start);
0131     ++m_depth;
0132     return true;
0133 }
0134 
0135 void DebugVisitor::postVisit(QmlJS::AST::Node* node)
0136 {
0137     Q_ASSERT(m_depth);
0138     --m_depth;
0139     printNode(node, End);
0140 }
0141 
0142 QString DebugVisitor::indent() const
0143 {
0144     return QString().fill(QLatin1Char(' '), m_depth * 2);
0145 }
0146 
0147 void DebugVisitor::printNode(QmlJS::AST::Node* node, Position position)
0148 {
0149     const QmlJS::AST::SourceLocation start = node->firstSourceLocation();
0150     const QmlJS::AST::SourceLocation end = node->lastSourceLocation();
0151     const QmlJS::AST::SourceLocation location = position == Start ? start : end;
0152 
0153     static QTextStream qout(stdout);
0154 
0155     qout << indent() << stringForAstKind(node->kind) << " [(" << start.startLine << ", " << start.startColumn << "), "
0156          << "(" << end.startLine << ", " << (end.startColumn + end.length) << ")]"
0157          << " \"" << m_session->symbolAt(location) << "\"" << Qt::endl;
0158 }
0159