From d4bc83a09d29a9f28f7d453eb9e0693225c3a32e Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Thu, 9 Apr 2009 17:45:59 +0200 Subject: Added missing files. --- src/declarative/qml/qmlscriptparser.cpp | 339 ++++++++++++++++++++++++++++++++ src/declarative/qml/qmlscriptparser_p.h | 43 ++++ 2 files changed, 382 insertions(+) create mode 100644 src/declarative/qml/qmlscriptparser.cpp create mode 100644 src/declarative/qml/qmlscriptparser_p.h diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp new file mode 100644 index 0000000..c74f4cb --- /dev/null +++ b/src/declarative/qml/qmlscriptparser.cpp @@ -0,0 +1,339 @@ + +#include "qmlscriptparser_p.h" + +#include "parser/javascriptengine_p.h" +#include "parser/javascriptparser_p.h" +#include "parser/javascriptlexer_p.h" +#include "parser/javascriptnodepool_p.h" +#include "parser/javascriptastvisitor_p.h" +#include "parser/javascriptast_p.h" +#include "parser/javascriptprettypretty_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +using namespace JavaScript; +using namespace QmlParser; + +namespace { + +class ProcessAST: protected AST::Visitor +{ + struct State { + State() : object(0), property(0) {} + State(Object *o) : object(o), property(0) {} + State(Object *o, Property *p) : object(o), property(p) {} + + Object *object; + Property *property; + }; + + struct StateStack : public QStack + { + void pushObject(Object *obj) + { + push(State(obj)); + } + + void pushProperty(const QString &name, int lineNumber) + { + const State &state = top(); + if (state.property) { + State s(state.property->getValue(), + state.property->getValue()->getProperty(name.toLatin1())); + s.property->line = lineNumber; + push(s); + } else { + State s(state.object, + state.object->getProperty(name.toLatin1())); + s.property->line = lineNumber; + push(s); + } + } + }; + +public: + ProcessAST(QmlScriptParser *parser); + virtual ~ProcessAST(); + + void operator()(AST::Node *node); + +protected: + using AST::Visitor::visit; + using AST::Visitor::endVisit; + + virtual bool visit(AST::UiObjectDefinition *node); + virtual void endVisit(AST::UiObjectDefinition *node); + + virtual bool visit(AST::UiPublicMember *node); + virtual bool visit(AST::UiObjectBinding *node); + virtual bool visit(AST::UiScriptBinding *node); + virtual bool visit(AST::UiArrayBinding *node); + + void accept(AST::Node *node); + + QString asString(AST::UiQualifiedId *node) const; + + const State state() const; + Object *currentObject() const; + Property *currentProperty() const; + + QString qualifiedNameId() const; + +private: + QmlScriptParser *_parser; + StateStack _stateStack; + QStringList _scope; +}; + +ProcessAST::ProcessAST(QmlScriptParser *parser) + : _parser(parser) +{ +} + +ProcessAST::~ProcessAST() +{ +} + +void ProcessAST::operator()(AST::Node *node) +{ + accept(node); +} + +void ProcessAST::accept(AST::Node *node) +{ + AST::Node::acceptChild(node, this); +} + +const ProcessAST::State ProcessAST::state() const +{ + if (_stateStack.isEmpty()) + return State(); + + return _stateStack.back(); +} + +Object *ProcessAST::currentObject() const +{ + return state().object; +} + +Property *ProcessAST::currentProperty() const +{ + return state().property; +} + +QString ProcessAST::qualifiedNameId() const +{ + return _scope.join(QLatin1String("/")); +} + +QString ProcessAST::asString(AST::UiQualifiedId *node) const +{ + QString s; + + for (AST::UiQualifiedId *it = node; it; it = it->next) { + s.append(it->name->asString()); + + if (it->next) + s.append(QLatin1Char('.')); + } + + return s; +} + +// UiObjectMember: T_PUBLIC T_IDENTIFIER T_IDENTIFIER T_COLON Expression UiObjectInitializer ; +bool ProcessAST::visit(AST::UiPublicMember *node) +{ + qWarning() << Q_FUNC_INFO << "not implemented"; + return false; +} + +// UiObjectMember: T_IDENTIFIER UiObjectInitializer ; +bool ProcessAST::visit(AST::UiObjectDefinition *node) +{ + const QString name = node->name->asString(); + bool isType = name.at(0).isUpper() && !name.contains(QLatin1Char('.')); + + _scope.append(name); + + if (! isType) { + qWarning() << "bad name for a class"; // ### FIXME + return false; + } + + // Class + const int typeId = _parser->findOrCreateTypeId(name); + int line = node->identifierToken.startLine; + + Object *obj = new Object; + obj->type = typeId; + obj->typeName = qualifiedNameId().toLatin1(); + obj->line = line; + + if (! _parser->tree()) { + _parser->setTree(obj); + _stateStack.pushObject(obj); + } else { + const State state = _stateStack.top(); + Value *v = new Value; + v->object = obj; + v->line = line; + if(state.property) + state.property->addValue(v); + else + state.object->getDefaultProperty()->addValue(v); + _stateStack.pushObject(obj); + } + + return true; +} + +// UiObjectMember: T_IDENTIFIER UiObjectInitializer ; +void ProcessAST::endVisit(AST::UiObjectDefinition *) +{ + _stateStack.pop(); + _scope.removeLast(); +} + +// UiObjectMember: UiQualifiedId T_COLON T_IDENTIFIER UiObjectInitializer ; +bool ProcessAST::visit(AST::UiObjectBinding *node) +{ + qWarning() << Q_FUNC_INFO << "not implemented"; + return false; +} + +// UiObjectMember: UiQualifiedId T_COLON Statement ; +bool ProcessAST::visit(AST::UiScriptBinding *node) +{ + const QString qualifiedId = asString(node->qualifiedId); + const QStringList str = qualifiedId.split(QLatin1Char('.')); + int line = node->colonToken.startLine; + + for(int ii = 0; ii < str.count(); ++ii) { + const QString s = str.at(ii); + _stateStack.pushProperty(s, line); + } + + QString primitive; + QTextStream out(&primitive); + PrettyPretty pp(out); + + if (node->statement->kind == AST::Node::Kind_ExpressionStatement) { + AST::ExpressionStatement *stmt = static_cast(node->statement); + + if (stmt->expression && stmt->expression->kind == AST::Node::Kind_IdentifierExpression) + primitive = static_cast(stmt->expression)->name->asString(); + else { + out << "{"; + pp(stmt->expression); + out << "}"; + } + } else { + pp(node->statement); + } + + + + + const State s = state(); + Value *v = new Value; + v->primitive = primitive; + v->line = line; + s.property->addValue(v); + + for(int ii = str.count() - 1; ii >= 0; --ii) + _stateStack.pop(); + + return false; +} + +// UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiObjectMemberList T_RBRACKET ; +bool ProcessAST::visit(AST::UiArrayBinding *node) +{ + qWarning() << Q_FUNC_INFO << "not implemented"; + return false; +} + +} // end of anonymous namespace + + +QmlScriptParser::QmlScriptParser() + : root(0) +{ +} + +QmlScriptParser::~QmlScriptParser() +{ +} + +bool QmlScriptParser::parse(const QByteArray &data, const QUrl &url) +{ + const QString fileName = url.toString(); + const QString code = QString::fromUtf8(data); // ### FIXME + + JavaScriptParser parser; + JavaScriptEnginePrivate driver; + + NodePool nodePool(fileName, &driver); + driver.setNodePool(&nodePool); + + Lexer lexer(&driver); + lexer.setCode(code, /*line = */ 1); + driver.setLexer(&lexer); + + if (! parser.parse(&driver)) { + _error = parser.errorMessage(); + return false; + } + + ProcessAST process(this); + process(parser.ast()); + + return true; +} + +QString QmlScriptParser::errorDescription() const +{ + return _error; +} + +QMap QmlScriptParser::nameSpacePaths() const +{ + qWarning() << Q_FUNC_INFO << "not implemented"; + return _nameSpacePaths; +} + +QStringList QmlScriptParser::types() const +{ + return _typeNames; +} + +Object *QmlScriptParser::tree() const +{ + return root; +} + +int QmlScriptParser::findOrCreateTypeId(const QString &name) +{ + int index = _typeNames.indexOf(name); + + if (index == -1) { + index = _typeNames.size(); + _typeNames.append(name); + } + + return index; +} + +void QmlScriptParser::setTree(Object *tree) +{ + Q_ASSERT(! root); + + root = tree; +} + + +QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlscriptparser_p.h b/src/declarative/qml/qmlscriptparser_p.h new file mode 100644 index 0000000..d9a557f --- /dev/null +++ b/src/declarative/qml/qmlscriptparser_p.h @@ -0,0 +1,43 @@ +#ifndef QMLSCRIPTPARSER_P_H +#define QMLSCRIPTPARSER_P_H + +#include +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QByteArray; + +class QmlScriptParser +{ +public: + QmlScriptParser(); + ~QmlScriptParser(); + + bool parse(const QByteArray &data, const QUrl &url = QUrl()); + QString errorDescription() const; + + QMap nameSpacePaths() const; + QStringList types() const; + + QmlParser::Object *tree() const; + +// ### private: + int findOrCreateTypeId(const QString &name); + void setTree(QmlParser::Object *tree); + +private: + QMap _nameSpacePaths; + QmlParser::Object *root; + QStringList _typeNames; + QString _error; +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QMLSCRIPTPARSER_P_H -- cgit v0.12