summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2009-04-09 15:45:59 (GMT)
committerRoberto Raggi <roberto.raggi@nokia.com>2009-04-24 07:52:33 (GMT)
commitd4bc83a09d29a9f28f7d453eb9e0693225c3a32e (patch)
tree655558edcab95333b985e0370b63c9771234bd3e /src/declarative
parent78e71084a29facdc5d2a81383b0f5bb1f78440bf (diff)
downloadQt-d4bc83a09d29a9f28f7d453eb9e0693225c3a32e.zip
Qt-d4bc83a09d29a9f28f7d453eb9e0693225c3a32e.tar.gz
Qt-d4bc83a09d29a9f28f7d453eb9e0693225c3a32e.tar.bz2
Added missing files.
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp339
-rw-r--r--src/declarative/qml/qmlscriptparser_p.h43
2 files changed, 382 insertions, 0 deletions
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 <QStack>
+#include <QtDebug>
+
+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<State>
+ {
+ 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<AST::ExpressionStatement *>(node->statement);
+
+ if (stmt->expression && stmt->expression->kind == AST::Node::Kind_IdentifierExpression)
+ primitive = static_cast<AST::IdentifierExpression *>(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<QString,QString> 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 <qml.h>
+#include <private/qmlcomponent_p.h>
+#include <private/qmlparser_p.h>
+
+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<QString,QString> nameSpacePaths() const;
+ QStringList types() const;
+
+ QmlParser::Object *tree() const;
+
+// ### private:
+ int findOrCreateTypeId(const QString &name);
+ void setTree(QmlParser::Object *tree);
+
+private:
+ QMap<QString,QString> _nameSpacePaths;
+ QmlParser::Object *root;
+ QStringList _typeNames;
+ QString _error;
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // QMLSCRIPTPARSER_P_H