File indexing completed on 2024-05-19 04:41:59
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