diff --git a/tests/manual/qml-ast2dot/main.cpp b/tests/manual/qml-ast2dot/main.cpp index d0c06dea4391afa653547fb86e06743d5fabd6b0..f3f5315088deb2cb5ea1f42f74e40432787f8b0e 100644 --- a/tests/manual/qml-ast2dot/main.cpp +++ b/tests/manual/qml-ast2dot/main.cpp @@ -79,6 +79,73 @@ public: cout << qPrintable(basename) << endl; } +protected: + void alignTerminals() { + out<<"{ rank=same;" << endl; + foreach (const QByteArray &terminalShape, _terminalShapes) { + out << " " << string(terminalShape) << ";" << endl; + } + out<<"}"<<endl; + } + + static QByteArray name(Node *ast) { +#ifdef __GNUC__ + QByteArray name = abi::__cxa_demangle(typeid(*ast).name(), 0, 0, 0) + 12; +#else + QByteArray name = typeid(*ast).name(); +#endif + return name; + } + + QString spell(const SourceLocation &token) { + return _src.mid(token.offset, token.length).replace('\'', "\\\\").replace('"', "\\\""); + } + + void terminal(const SourceLocation &token) { + if (!token.isValid()) + return; + + static int count = 1; + QByteArray id = 't' + QByteArray::number(count++); + Node *node = _stack.last(); + _connections.append(qMakePair(_id[node], id)); + + QByteArray t; + t.append(id); + t.append(" [label = \""); + t.append(spell(token)); + t.append("\" shape=rect]"); + _terminalShapes.append(t); + } + + virtual void nonterminal(Node *ast) { + Node::accept(ast, this); + } + + virtual void node(Node *ast) { + out << _id[ast].constData() << " [label=\"" << name(ast).constData() << "\"];" << endl; + } + + virtual bool preVisit(Node *ast) { + static int count = 1; + const QByteArray id = 'n' + QByteArray::number(count++); + _id[ast] = id; + + + if (! _stack.isEmpty()) + _connections.append(qMakePair(_id[_stack.last()], id)); + + _stack.append(ast); + + node(ast); + + return true; + } + + virtual void postVisit(Node *) { + _stack.removeLast(); + } + protected: // visiting methods: virtual bool visit(UiImport *ast) { terminal(ast->importToken); @@ -168,6 +235,9 @@ protected: // visiting methods: return false; } + virtual bool visit(UiFormal *ast) { terminal(ast->identifierToken); terminal(ast->asToken); terminal(ast->aliasToken); return false; } + virtual bool visit(UiSignature *ast) { terminal(ast->lparenToken); nonterminal(ast->formals); terminal(ast->rparenToken); return false; } + virtual bool visit(StringLiteral *ast) { terminal(ast->literalToken); return false; } virtual bool visit(NumericLiteral *ast) { terminal(ast->literalToken); return false; } virtual bool visit(TrueLiteral *ast) { terminal(ast->trueToken); return false; } @@ -178,73 +248,65 @@ protected: // visiting methods: virtual bool visit(UnaryPlusExpression *ast) { terminal(ast->plusToken); nonterminal(ast->expression); return false; } virtual bool visit(UnaryMinusExpression *ast) { terminal(ast->minusToken); nonterminal(ast->expression); return false; } virtual bool visit(NestedExpression *ast) { terminal(ast->lparenToken); nonterminal(ast->expression); terminal(ast->rparenToken); return false; } - -protected: - void alignTerminals() { - out<<"{ rank=same;" << endl; - foreach (const QByteArray &terminalShape, _terminalShapes) { - out << " " << string(terminalShape) << ";" << endl; - } - out<<"}"<<endl; - } - - static QByteArray name(Node *ast) { -#ifdef __GNUC__ - QByteArray name = abi::__cxa_demangle(typeid(*ast).name(), 0, 0, 0) + 12; -#else - QByteArray name = typeid(*ast).name(); -#endif - return name; - } - - QString spell(const SourceLocation &token) { - return _src.mid(token.offset, token.length).replace('\'', "\\\\").replace('"', "\\\""); - } - - void terminal(const SourceLocation &token) { - if (!token.isValid()) - return; - - static int count = 1; - QByteArray id = 't' + QByteArray::number(count++); - Node *node = _stack.last(); - _connections.append(qMakePair(_id[node], id)); - - QByteArray t; - t.append(id); - t.append(" [label = \""); - t.append(spell(token)); - t.append("\" shape=rect]"); - _terminalShapes.append(t); - } - - virtual void nonterminal(Node *ast) { - Node::accept(ast, this); - } - - virtual void node(Node *ast) { - out << _id[ast].constData() << " [label=\"" << name(ast).constData() << "\"];" << endl; - } - - virtual bool preVisit(Node *ast) { - static int count = 1; - const QByteArray id = 'n' + QByteArray::number(count++); - _id[ast] = id; - - - if (! _stack.isEmpty()) - _connections.append(qMakePair(_id[_stack.last()], id)); - - _stack.append(ast); - - node(ast); - - return true; - } - - virtual void postVisit(Node *) { - _stack.removeLast(); - } + virtual bool visit(ThisExpression *ast) { terminal(ast->thisToken); return false; } + virtual bool visit(NullExpression *ast) { terminal(ast->nullToken); return false; } + virtual bool visit(RegExpLiteral *ast) { terminal(ast->literalToken); return false; } + virtual bool visit(ArrayLiteral *ast) { terminal(ast->lbracketToken); nonterminal(ast->elements); terminal(ast->commaToken); nonterminal(ast->elision); terminal(ast->rbracketToken); return false; } + virtual bool visit(ObjectLiteral *ast) { terminal(ast->lbraceToken); nonterminal(ast->properties); terminal(ast->rbraceToken); return false; } + virtual bool visit(ElementList *ast) { nonterminal(ast->next); terminal(ast->commaToken); nonterminal(ast->elision); nonterminal(ast->expression); return false; } + virtual bool visit(Elision *ast) { nonterminal(ast->next); terminal(ast->commaToken); return false; } + virtual bool visit(PropertyNameAndValueList *ast) { nonterminal(ast->name); terminal(ast->colonToken); nonterminal(ast->value); terminal(ast->commaToken); nonterminal(ast->next); return false; } + virtual bool visit(IdentifierPropertyName *ast) { terminal(ast->propertyNameToken); return false; } + virtual bool visit(StringLiteralPropertyName *ast) { terminal(ast->propertyNameToken); return false; } + virtual bool visit(NumericLiteralPropertyName *ast) { terminal(ast->propertyNameToken); return false; } + virtual bool visit(ArrayMemberExpression *ast) { nonterminal(ast->base); terminal(ast->lbracketToken); nonterminal(ast->expression); terminal(ast->rbracketToken); return false; } + virtual bool visit(NewMemberExpression *ast) { terminal(ast->newToken); nonterminal(ast->base); terminal(ast->lparenToken); nonterminal(ast->arguments); terminal(ast->rparenToken); return false; } + virtual bool visit(NewExpression *ast) { terminal(ast->newToken); nonterminal(ast->expression); return false; } + virtual bool visit(CallExpression *ast) { nonterminal(ast->base); terminal(ast->lparenToken); nonterminal(ast->arguments); terminal(ast->rparenToken); return false; } + virtual bool visit(ArgumentList *ast) { nonterminal(ast->expression); terminal(ast->commaToken); nonterminal(ast->next); return false; } + virtual bool visit(PostIncrementExpression *ast) { nonterminal(ast->base); terminal(ast->incrementToken); return false; } + virtual bool visit(PostDecrementExpression *ast) { nonterminal(ast->base); terminal(ast->decrementToken); return false; } + virtual bool visit(DeleteExpression *ast) { terminal(ast->deleteToken); nonterminal(ast->expression); return false; } + virtual bool visit(VoidExpression *ast) { terminal(ast->voidToken); nonterminal(ast->expression); return false; } + virtual bool visit(TypeOfExpression *ast) { terminal(ast->typeofToken); nonterminal(ast->expression); return false; } + virtual bool visit(PreIncrementExpression *ast) { terminal(ast->incrementToken); nonterminal(ast->expression); return false; } + virtual bool visit(PreDecrementExpression *ast) { terminal(ast->decrementToken); nonterminal(ast->expression); return false; } + virtual bool visit(TildeExpression *ast) { terminal(ast->tildeToken); nonterminal(ast->expression); return false; } + virtual bool visit(NotExpression *ast) { terminal(ast->notToken); nonterminal(ast->expression); return false; } + virtual bool visit(ConditionalExpression *ast) { nonterminal(ast->expression); terminal(ast->questionToken); nonterminal(ast->ok); terminal(ast->colonToken); nonterminal(ast->ko); return false; } + virtual bool visit(Expression *ast) { nonterminal(ast->left); terminal(ast->commaToken); nonterminal(ast->right); return false; } + virtual bool visit(Block *ast) { terminal(ast->lbraceToken); nonterminal(ast->statements); terminal(ast->rbraceToken); return false; } + virtual bool visit(VariableStatement *ast) { terminal(ast->declarationKindToken); nonterminal(ast->declarations); terminal(ast->semicolonToken); return false; } + virtual bool visit(VariableDeclaration *ast) { terminal(ast->identifierToken); nonterminal(ast->expression); return false; } + virtual bool visit(VariableDeclarationList *ast) { nonterminal(ast->declaration); terminal(ast->commaToken); nonterminal(ast->next); return false; } + virtual bool visit(EmptyStatement* ast) { terminal(ast->semicolonToken); return false; } + virtual bool visit(ExpressionStatement *ast) { nonterminal(ast->expression); terminal(ast->semicolonToken); return false; } + virtual bool visit(IfStatement *ast) { terminal(ast->ifToken); terminal(ast->lparenToken); nonterminal(ast->expression); terminal(ast->rparenToken); nonterminal(ast->ok); terminal(ast->elseToken); nonterminal(ast->ko); return false; } + virtual bool visit(DoWhileStatement *ast) { terminal(ast->doToken); nonterminal(ast->statement); terminal(ast->whileToken); terminal(ast->lparenToken); nonterminal(ast->expression); terminal(ast->rparenToken); terminal(ast->semicolonToken); return false; } + +// TODO: visitors for: +// WhileStatement +// ForStatement +// LocalForStatement +// ForEachStatement +// LocalForEachStatement +// ContinueStatement +// BreakStatement +// ReturnStatement +// WithStatement +// CaseBlock +// SwitchStatement +// CaseClause +// DefaultClause +// LabelledStatement +// ThrowStatement +// Catch +// Finally +// TryStatement +// FunctionExpression +// FunctionDeclaration +// DebuggerStatement +// UiParameterList private: QHash<Node *, QByteArray> _id;