aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-03-20 21:46:29 +0100
committerLars Knoll <lars.knoll@qt.io>2018-04-26 21:37:42 +0000
commit09cd6f8020b7c25eaaf959a48c452b01aebcf627 (patch)
tree69749d463a95d123aabcfea807a0a689bc8fcd2f /src
parentcfac31cd823bd8eb83900adeecbfd3d789a3ee1d (diff)
Add support for 'super' and 'new.target' to the AST
Codegen will still throw a Syntax error on it though. Change-Id: I292dd166ad8cb4a62f2bcfa9637bdc76cf95bb51 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4codegen.cpp20
-rw-r--r--src/qml/compiler/qv4codegen_p.h1
-rw-r--r--src/qml/parser/qqmljs.g54
-rw-r--r--src/qml/parser/qqmljsast.cpp9
-rw-r--r--src/qml/parser/qqmljsast_p.h21
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h1
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h3
7 files changed, 90 insertions, 19 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 4b2a98bcad..29a916bd7e 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1542,11 +1542,31 @@ bool Codegen::visit(FalseLiteral *)
return false;
}
+bool Codegen::visit(SuperLiteral *ast)
+{
+ if (hasError)
+ return false;
+
+ throwSyntaxError(ast->superToken, QLatin1String("Support for 'super' keyword not implemented"));
+ return false;
+}
+
bool Codegen::visit(FieldMemberExpression *ast)
{
if (hasError)
return false;
+ if (AST::IdentifierExpression *id = AST::cast<AST::IdentifierExpression *>(ast->base)) {
+ if (id->name == QLatin1String("new")) {
+ // new.target
+ if (ast->name != QLatin1String("target")) {
+ throwSyntaxError(ast->identifierToken, QLatin1String("Expected 'target' after 'new.'."));
+ return false;
+ }
+ throwSyntaxError(ast->identifierToken, QLatin1String("Support for 'new.target' unimplemented."));
+ }
+ }
+
Reference base = expression(ast->base);
if (hasError)
return false;
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 5ff0aa5c30..6de6affdcc 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -561,6 +561,7 @@ protected:
bool visit(AST::ConditionalExpression *ast) override;
bool visit(AST::DeleteExpression *ast) override;
bool visit(AST::FalseLiteral *ast) override;
+ bool visit(AST::SuperLiteral *ast) override;
bool visit(AST::FieldMemberExpression *ast) override;
bool visit(AST::TaggedTemplate *ast) override;
bool visit(AST::FunctionExpression *ast) override;
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 4a4e3dfd12..7defdb8a08 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -1758,9 +1758,13 @@ PropertyDefinition: IdentifierReference;
} break;
./
--- ### using this production should result in a syntax error when used in an ObjectLiteral
+-- Using this production should result in a syntax error when used in an ObjectLiteral
PropertyDefinition: CoverInitializedName;
-/. case $rule_number: { UNIMPLEMENTED; } ./
+/. case $rule_number: {
+ syntaxError(loc(1), "Expected token ':' after identifier.");
+ return false;
+ } break;
+./
UiPropertyDefinition: UiPropertyName T_COLON AssignmentExpression_In;
/. case $rule_number: Q_FALLTHROUGH(); ./
@@ -1911,6 +1915,18 @@ TemplateLiteral: T_TEMPLATE_HEAD Expression TemplateSpans;
MemberExpression: PrimaryExpression;
+Super: T_SUPER;
+/.
+ case $rule_number: {
+ AST::SuperLiteral *node = new (pool) AST::SuperLiteral();
+ node->superToken = loc(1);
+ sym(1).Node = node;
+ } break;
+./
+
+
+MemberExpression: Super T_LBRACKET Expression_In T_RBRACKET;
+/. case $rule_number: Q_FALLTHROUGH(); ./
MemberExpression: MemberExpression T_LBRACKET Expression_In T_RBRACKET;
/.
case $rule_number: {
@@ -1921,6 +1937,18 @@ MemberExpression: MemberExpression T_LBRACKET Expression_In T_RBRACKET;
} break;
./
+
+-- the identifier has to be "target", catched at codegen time
+NewTarget: T_NEW T_DOT T_IDENTIFIER;
+/. case $rule_number:
+ {
+ AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
+ node->identifierToken= loc(1);
+ sym(1).Node = node;
+ } Q_FALLTHROUGH();
+./
+MemberExpression: Super T_DOT IdentifierName;
+/. case $rule_number: Q_FALLTHROUGH(); ./
MemberExpression: MemberExpression T_DOT IdentifierName;
/.
case $rule_number: {
@@ -1931,11 +1959,7 @@ MemberExpression: MemberExpression T_DOT IdentifierName;
} break;
./
-MemberExpression: SuperProperty;
-/. case $rule_number: { UNIMPLEMENTED; } ./
-
MemberExpression: MetaProperty;
-/. case $rule_number: { UNIMPLEMENTED; } ./
MemberExpression: T_NEW MemberExpression T_LPAREN Arguments T_RPAREN;
/.
@@ -1948,22 +1972,17 @@ MemberExpression: T_NEW MemberExpression T_LPAREN Arguments T_RPAREN;
} break;
./
-SuperProperty: T_SUPER T_LBRACKET Expression_In T_RBRACKET;
-
-SuperProperty: T_SUPER T_DOT IdentifierName;
-
MetaProperty: NewTarget;
-NewTarget: T_NEW T_DOT T_IDENTIFIER; -- ### the identifier has to be "target";
NewExpression: MemberExpression;
NewExpression: T_NEW NewExpression;
/.
case $rule_number: {
- AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
- node->newToken = loc(1);
- sym(1).Node = node;
+ AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
+ node->newToken = loc(1);
+ sym(1).Node = node;
} break;
./
@@ -1988,9 +2007,8 @@ CallExpression: MemberExpression T_LPAREN Arguments T_RPAREN;
} break;
./
-CallExpression: SuperCall;
-/. case $rule_number: { UNIMPLEMENTED; } ./
-
+CallExpression: Super T_LPAREN Arguments T_RPAREN;
+/. case $rule_number: Q_FALLTHROUGH(); ./
CallExpression: CallExpression T_LPAREN Arguments T_RPAREN;
/.
case $rule_number: {
@@ -2021,8 +2039,6 @@ CallExpression: CallExpression T_DOT IdentifierName;
} break;
./
-SuperCall: T_SUPER T_LPAREN Arguments T_RPAREN;
-
Arguments: ;
/.
case $rule_number: {
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index b480cdf76c..829887ab9d 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -147,6 +147,15 @@ void FalseLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+void SuperLiteral::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ }
+
+ visitor->endVisit(this);
+}
+
+
void StringLiteral::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 60a3fdf589..cd5c3a1021 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -148,6 +148,7 @@ public:
Kind_Expression,
Kind_ExpressionStatement,
Kind_FalseLiteral,
+ Kind_SuperLiteral,
Kind_FieldMemberExpression,
Kind_Finally,
Kind_ForEachStatement,
@@ -391,6 +392,26 @@ public:
SourceLocation falseToken;
};
+class QML_PARSER_EXPORT SuperLiteral : public ExpressionNode
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(SuperLiteral)
+
+ SuperLiteral() { kind = K; }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return superToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return superToken; }
+
+// attributes
+ SourceLocation superToken;
+};
+
+
class QML_PARSER_EXPORT NumericLiteral: public ExpressionNode
{
public:
diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h
index 7766927f8e..1bf8ce0fb8 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -89,6 +89,7 @@ class IdentifierExpression;
class NullExpression;
class TrueLiteral;
class FalseLiteral;
+class SuperLiteral;
class NumericLiteral;
class StringLiteral;
class TemplateLiteral;
diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h
index 1e6ce8eaee..d995ce6f0b 100644
--- a/src/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/parser/qqmljsastvisitor_p.h
@@ -122,6 +122,9 @@ public:
virtual bool visit(FalseLiteral *) { return true; }
virtual void endVisit(FalseLiteral *) {}
+ virtual bool visit(SuperLiteral *) { return true; }
+ virtual void endVisit(SuperLiteral *) {}
+
virtual bool visit(StringLiteral *) { return true; }
virtual void endVisit(StringLiteral *) {}