aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-04 10:56:19 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-09 20:47:27 +0000
commit128485ccdb4f1c6f1bf1ebea85c5bed749cacd7a (patch)
tree350c795726910498f2a2ee7f9caa71018ae7ad5a /src/qml/parser
parent20a5d1ab3f47b4da6ba39143beaafedb26dbad6a (diff)
Add some basic support for for-of loops
The support is basically at the same level as for for-in at the moment. Currently unimplemented: * Destructuring * Proper lexical scoping * calling iterator.throw()/return() when required Change-Id: If193ce0b054c4315fc16b7e174334a31b2730dcf Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/parser')
-rw-r--r--src/qml/parser/qqmljs.g31
-rw-r--r--src/qml/parser/qqmljsast_p.h11
-rw-r--r--src/qml/parser/qqmljskeywords_p.h5
-rw-r--r--src/qml/parser/qqmljslexer.cpp1
4 files changed, 35 insertions, 13 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index c25f3395e2..8e71b8a42b 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -262,6 +262,7 @@ public:
int ival;
double dval;
AST::VariableScope scope;
+ AST::ForEachType forEachType;
AST::ArgumentList *ArgumentList;
AST::CaseBlock *CaseBlock;
AST::CaseClause *CaseClause;
@@ -3125,37 +3126,47 @@ IterationStatement: T_FOR T_LPAREN LexicalDeclaration T_SEMICOLON ExpressionOpt_
} break;
./
-IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression_In T_RPAREN Statement;
+InOrOf: T_IN;
+/.
+ case $rule_number: {
+ sym(1).forEachType = AST::ForEachType::In;
+ } break;
+./
+
+InOrOf: T_OF;
+/.
+ case $rule_number: {
+ sym(1).forEachType = AST::ForEachType::Of;
+ } break;
+./
+
+IterationStatement: T_FOR T_LPAREN LeftHandSideExpression InOrOf Expression_In T_RPAREN Statement;
/.
case $rule_number: {
AST::ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
- node->inToken = loc(4);
+ node->inOfToken = loc(4);
node->rparenToken = loc(6);
+ node->type = sym(4).forEachType;
sym(1).Node = node;
} break;
./
-IterationStatement: T_FOR T_LPAREN ForDeclaration T_IN Expression_In T_RPAREN Statement;
+IterationStatement: T_FOR T_LPAREN ForDeclaration InOrOf Expression_In T_RPAREN Statement;
/.
case $rule_number: {
AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(sym(3).PatternElement, sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
node->varToken = loc(3);
- node->inToken = loc(4);
+ node->inOfToken = loc(4);
node->rparenToken = loc(6);
+ node->type = sym(4).forEachType;
sym(1).Node = node;
} break;
./
-
-IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_OF AssignmentExpression_In T_RPAREN Statement; -- [lookahead ≠ let]
-/. case $rule_number: { UNIMPLEMENTED; } ./
-IterationStatement: T_FOR T_LPAREN ForDeclaration T_OF Expression_In T_RPAREN Statement;
-/. case $rule_number: { UNIMPLEMENTED; } ./
-
ForDeclaration: LetOrConst ForBinding;
/. case $rule_number: Q_FALLTHROUGH(); ./
ForDeclaration: Var ForBinding;
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index c83a459506..e54d1aea31 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -1701,6 +1701,11 @@ public:
SourceLocation rparenToken;
};
+enum class ForEachType {
+ In,
+ Of
+};
+
class QML_PARSER_EXPORT ForEachStatement: public Statement
{
public:
@@ -1724,8 +1729,9 @@ public:
Statement *statement;
SourceLocation forToken;
SourceLocation lparenToken;
- SourceLocation inToken;
+ SourceLocation inOfToken;
SourceLocation rparenToken;
+ ForEachType type;
};
class QML_PARSER_EXPORT LocalForEachStatement: public Statement
@@ -1752,8 +1758,9 @@ public:
SourceLocation forToken;
SourceLocation lparenToken;
SourceLocation varToken;
- SourceLocation inToken;
+ SourceLocation inOfToken;
SourceLocation rparenToken;
+ ForEachType type;
};
class QML_PARSER_EXPORT ContinueStatement: public Statement
diff --git a/src/qml/parser/qqmljskeywords_p.h b/src/qml/parser/qqmljskeywords_p.h
index 9cc47469e5..40094ecdf8 100644
--- a/src/qml/parser/qqmljskeywords_p.h
+++ b/src/qml/parser/qqmljskeywords_p.h
@@ -76,10 +76,13 @@ static inline int classify2(const QChar *s, int parseModeFlags) {
return Lexer::T_IN;
}
}
- else if ((parseModeFlags & Lexer::QmlMode) && s[0].unicode() == 'o') {
+ else if (s[0].unicode() == 'o') {
if (s[1].unicode() == 'n') {
return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_ON : Lexer::T_IDENTIFIER;
}
+ else if (s[1].unicode() == 'f') {
+ return Lexer::T_OF;
+ }
}
return Lexer::T_IDENTIFIER;
}
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index 3dbe535bcf..69e73f1374 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -1343,6 +1343,7 @@ static const int uriTokens[] = {
QQmlJSGrammar::T_FUNCTION,
QQmlJSGrammar::T_IF,
QQmlJSGrammar::T_IN,
+ QQmlJSGrammar::T_OF,
QQmlJSGrammar::T_INSTANCEOF,
QQmlJSGrammar::T_NEW,
QQmlJSGrammar::T_NULL,