aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-06-30 21:04:51 +0200
committerLars Knoll <lars.knoll@qt.io>2018-07-03 08:09:09 +0000
commitdcbdb306f4442199384a71d532a3610a84d13fd5 (patch)
treee51520aafbc9dd12cd8d0013070d67fcc32fe13a /src/qml/parser
parent6d8dbba4624c8a453ba13ff009f011f2946422bb (diff)
Fix naming of classes in class expressions
As with function expressions, class expressions also get an implicitly defined name if they are directly assigned to a named variable. Change-Id: I5fda9d74c1c299107f15b82245333b54ca6d8917 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/parser')
-rw-r--r--src/qml/parser/qqmljs.g16
-rw-r--r--src/qml/parser/qqmljsast.cpp25
-rw-r--r--src/qml/parser/qqmljsast_p.h6
3 files changed, 46 insertions, 1 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 9231001f17..cd40a77299 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -1779,6 +1779,8 @@ CoverInitializedName: IdentifierReference Initializer_In;
// if initializer is an anonymous function expression, we need to assign identifierref as it's name
if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression))
f->name = stringRef(1);
+ if (auto *c = asAnonymousClassDefinition(sym(2).Expression))
+ c->name = stringRef(1);
AST::BinaryExpression *assignment = new (pool) AST::BinaryExpression(left, QSOperator::Assign, sym(2).Expression);
AST::PatternProperty *node = new (pool) AST::PatternProperty(name, assignment);
node->colonToken = loc(1);
@@ -1797,6 +1799,10 @@ PropertyDefinition: PropertyName T_COLON AssignmentExpression_In;
if (!AST::cast<AST::ComputedPropertyName *>(sym(1).PropertyName))
f->name = driver->newStringRef(sym(1).PropertyName->asString());
}
+ if (auto *c = asAnonymousClassDefinition(sym(3).Expression)) {
+ if (!AST::cast<AST::ComputedPropertyName *>(sym(1).PropertyName))
+ c->name = driver->newStringRef(sym(1).PropertyName->asString());
+ }
node->colonToken = loc(2);
sym(1).Node = node;
} break;
@@ -2520,6 +2526,10 @@ AssignmentExpression_In: LeftHandSideExpression T_EQ AssignmentExpression_In;
if (auto *id = AST::cast<AST::IdentifierExpression *>(sym(1).Expression))
f->name = id->name;
}
+ if (auto *c = asAnonymousClassDefinition(sym(3).Expression)) {
+ if (auto *id = AST::cast<AST::IdentifierExpression *>(sym(1).Expression))
+ c->name = id->name;
+ }
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Assign, sym(3).Expression);
node->operatorToken = loc(2);
@@ -2832,6 +2842,8 @@ VariableDeclaration_In: BindingIdentifier InitializerOpt_In;
// if initializer is an anonymous function expression, we need to assign identifierref as it's name
if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression))
f->name = stringRef(1);
+ if (auto *c = asAnonymousClassDefinition(sym(2).Expression))
+ c->name = stringRef(1);
} break;
./
@@ -2958,6 +2970,8 @@ BindingProperty: BindingIdentifier InitializerOpt_In;
// if initializer is an anonymous function expression, we need to assign identifierref as it's name
if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression))
f->name = stringRef(1);
+ if (auto *c = asAnonymousClassDefinition(sym(2).Expression))
+ c->name = stringRef(1);
sym(1).Node = new (pool) AST::PatternProperty(name, stringRef(1), sym(2).Expression);
} break;
./
@@ -2986,6 +3000,8 @@ BindingElement: BindingIdentifier InitializerOpt_In;
// if initializer is an anonymous function expression, we need to assign identifierref as it's name
if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression))
f->name = stringRef(1);
+ if (auto *c = asAnonymousClassDefinition(sym(2).Expression))
+ c->name = stringRef(1);
sym(1).Node = node;
} break;
./
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 89ef861c85..b8c4a58a13 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -55,6 +55,16 @@ FunctionExpression *asAnonymousFunctionDefinition(Node *n)
return f;
}
+ClassExpression *asAnonymousClassDefinition(Node *n)
+{
+ if (!n)
+ return nullptr;
+ ClassExpression *c = n->asClassDefinition();
+ if (!c || !c->name.isNull())
+ return nullptr;
+ return c;
+}
+
void Node::accept(Visitor *visitor)
{
@@ -105,6 +115,11 @@ FunctionExpression *Node::asFunctionDefinition()
return nullptr;
}
+ClassExpression *Node::asClassDefinition()
+{
+ return nullptr;
+}
+
ExpressionNode *ExpressionNode::expressionCast()
{
return this;
@@ -174,6 +189,11 @@ FunctionExpression *NestedExpression::asFunctionDefinition()
return expression->asFunctionDefinition();
}
+ClassExpression *NestedExpression::asClassDefinition()
+{
+ return expression->asClassDefinition();
+}
+
void ThisExpression::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
@@ -1296,6 +1316,11 @@ void ClassExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+ClassExpression *ClassExpression::asClassDefinition()
+{
+ return this;
+}
+
void ClassDeclaration::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 6a4e1e6ea1..2cf2bcb736 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -129,6 +129,7 @@ T1 cast(T2 *ast)
}
FunctionExpression *asAnonymousFunctionDefinition(AST::Node *n);
+ClassExpression *asAnonymousClassDefinition(AST::Node *n);
class QML_PARSER_EXPORT Node: public Managed
{
@@ -257,6 +258,7 @@ public:
virtual Pattern *patternCast();
// implements the IsFunctionDefinition rules in the spec
virtual FunctionExpression *asFunctionDefinition();
+ virtual ClassExpression *asClassDefinition();
void accept(Visitor *visitor);
static void accept(Node *node, Visitor *visitor);
@@ -314,6 +316,7 @@ public:
{ return rparenToken; }
FunctionExpression *asFunctionDefinition() override;
+ ClassExpression *asClassDefinition() override;
// attributes
@@ -2110,7 +2113,6 @@ public:
FunctionExpression *asFunctionDefinition() override;
-
// attributes
QStringRef name;
bool isArrowFunction = false;
@@ -2237,6 +2239,8 @@ public:
SourceLocation lastSourceLocation() const override
{ return rbraceToken; }
+ ClassExpression *asClassDefinition() override;
+
// attributes
QStringRef name;
ExpressionNode *heritage;