mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Bug 1611777 - Part 4: super
can't occur on the left-hand side of an optional chain. r=yulia
Moves the `isSuper()` method from the base class to the (non-optional) derived classes, because `super?.x` isn't valid syntax, so it's confusing to be able to ask if an optional property access is applied on `super`. The next part will further simplify `BytecodeEmitter::emitDelete{Element,Property}InOptChain()`. Differential Revision: https://phabricator.services.mozilla.com/D61151 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
f06ccdae60
commit
15e84c1e7a
@ -2883,11 +2883,14 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) {
|
||||
PropertyAccessBase* prop = &pn->as<PropertyAccessBase>();
|
||||
MOZ_ASSERT(prop->pn_pos.encloses(prop->expression().pn_pos));
|
||||
|
||||
bool isSuper =
|
||||
prop->is<PropertyAccess>() && prop->as<PropertyAccess>().isSuper();
|
||||
|
||||
RootedValue expr(cx);
|
||||
RootedValue propname(cx);
|
||||
RootedAtom pnAtom(cx, prop->key().atom());
|
||||
|
||||
if (prop->isSuper()) {
|
||||
if (isSuper) {
|
||||
if (!builder.super(&prop->expression().pn_pos, &expr)) {
|
||||
return false;
|
||||
}
|
||||
@ -2910,9 +2913,12 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) {
|
||||
MOZ_ASSERT(elem->pn_pos.encloses(elem->expression().pn_pos));
|
||||
MOZ_ASSERT(elem->pn_pos.encloses(elem->key().pn_pos));
|
||||
|
||||
bool isSuper =
|
||||
elem->is<PropertyByValue>() && elem->as<PropertyByValue>().isSuper();
|
||||
|
||||
RootedValue expr(cx), key(cx);
|
||||
|
||||
if (elem->isSuper()) {
|
||||
if (isSuper) {
|
||||
if (!builder.super(&elem->expression().pn_pos, &expr)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -6806,11 +6806,13 @@ bool BytecodeEmitter::emitDeleteOptionalChain(UnaryNode* deleteNode) {
|
||||
|
||||
bool BytecodeEmitter::emitDeletePropertyInOptChain(PropertyAccessBase* propExpr,
|
||||
OptionalEmitter& oe) {
|
||||
PropOpEmitter poe(this, PropOpEmitter::Kind::Delete,
|
||||
propExpr->isSuper() ? PropOpEmitter::ObjKind::Super
|
||||
: PropOpEmitter::ObjKind::Other);
|
||||
bool isSuper = propExpr->is<PropertyAccess>() &&
|
||||
propExpr->as<PropertyAccess>().isSuper();
|
||||
PropOpEmitter poe(
|
||||
this, PropOpEmitter::Kind::Delete,
|
||||
isSuper ? PropOpEmitter::ObjKind::Super : PropOpEmitter::ObjKind::Other);
|
||||
|
||||
if (propExpr->isSuper()) {
|
||||
if (isSuper) {
|
||||
// The expression |delete super.foo;| has to evaluate |super.foo|,
|
||||
// which could throw if |this| hasn't yet been set by a |super(...)|
|
||||
// call or the super-base is not an object, before throwing a
|
||||
@ -6853,9 +6855,11 @@ bool BytecodeEmitter::emitDeletePropertyInOptChain(PropertyAccessBase* propExpr,
|
||||
|
||||
bool BytecodeEmitter::emitDeleteElementInOptChain(PropertyByValueBase* elemExpr,
|
||||
OptionalEmitter& oe) {
|
||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Delete,
|
||||
elemExpr->isSuper() ? ElemOpEmitter::ObjKind::Super
|
||||
: ElemOpEmitter::ObjKind::Other);
|
||||
bool isSuper = elemExpr->is<PropertyByValue>() &&
|
||||
elemExpr->as<PropertyByValue>().isSuper();
|
||||
ElemOpEmitter eoe(
|
||||
this, ElemOpEmitter::Kind::Delete,
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
|
||||
|
||||
if (!eoe.prepareForObj()) {
|
||||
// [stack]
|
||||
@ -7205,7 +7209,7 @@ bool BytecodeEmitter::emitOptionalCalleeAndThis(ParseNode* callee,
|
||||
case ParseNodeKind::OptionalDotExpr: {
|
||||
MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
|
||||
OptionalPropertyAccess* prop = &callee->as<OptionalPropertyAccess>();
|
||||
bool isSuper = prop->isSuper();
|
||||
bool isSuper = false;
|
||||
|
||||
PropOpEmitter& poe = cone.prepareForPropCallee(isSuper);
|
||||
if (!emitOptionalDotExpression(prop, poe, isSuper, oe)) {
|
||||
@ -7229,7 +7233,8 @@ bool BytecodeEmitter::emitOptionalCalleeAndThis(ParseNode* callee,
|
||||
|
||||
case ParseNodeKind::OptionalElemExpr: {
|
||||
OptionalPropertyByValue* elem = &callee->as<OptionalPropertyByValue>();
|
||||
bool isSuper = elem->isSuper();
|
||||
bool isSuper = false;
|
||||
|
||||
ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper);
|
||||
if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) {
|
||||
// [stack] CALLEE THIS
|
||||
@ -7240,6 +7245,7 @@ bool BytecodeEmitter::emitOptionalCalleeAndThis(ParseNode* callee,
|
||||
case ParseNodeKind::ElemExpr: {
|
||||
PropertyByValue* elem = &callee->as<PropertyByValue>();
|
||||
bool isSuper = elem->isSuper();
|
||||
|
||||
ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper);
|
||||
if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) {
|
||||
// [stack] CALLEE THIS
|
||||
@ -7722,10 +7728,9 @@ bool BytecodeEmitter::emitOptionalTree(ParseNode* pn, OptionalEmitter& oe) {
|
||||
switch (kind) {
|
||||
case ParseNodeKind::OptionalDotExpr: {
|
||||
OptionalPropertyAccess* prop = &pn->as<OptionalPropertyAccess>();
|
||||
bool isSuper = prop->isSuper();
|
||||
bool isSuper = false;
|
||||
PropOpEmitter poe(this, PropOpEmitter::Kind::Get,
|
||||
isSuper ? PropOpEmitter::ObjKind::Super
|
||||
: PropOpEmitter::ObjKind::Other);
|
||||
PropOpEmitter::ObjKind::Other);
|
||||
if (!emitOptionalDotExpression(prop, poe, isSuper, oe)) {
|
||||
return false;
|
||||
}
|
||||
@ -7745,10 +7750,9 @@ bool BytecodeEmitter::emitOptionalTree(ParseNode* pn, OptionalEmitter& oe) {
|
||||
|
||||
case ParseNodeKind::OptionalElemExpr: {
|
||||
OptionalPropertyByValue* elem = &pn->as<OptionalPropertyByValue>();
|
||||
bool isSuper = elem->isSuper();
|
||||
bool isSuper = false;
|
||||
ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
|
||||
isSuper ? ElemOpEmitter::ObjKind::Super
|
||||
: ElemOpEmitter::ObjKind::Other);
|
||||
ElemOpEmitter::ObjKind::Other);
|
||||
|
||||
if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) {
|
||||
return false;
|
||||
|
@ -1944,11 +1944,6 @@ class PropertyAccessBase : public BinaryNode {
|
||||
PropertyName& name() const {
|
||||
return *right()->as<NameNode>().atom()->asPropertyName();
|
||||
}
|
||||
|
||||
bool isSuper() const {
|
||||
// ParseNodeKind::SuperBase cannot result from any expression syntax.
|
||||
return expression().isKind(ParseNodeKind::SuperBase);
|
||||
}
|
||||
};
|
||||
|
||||
class PropertyAccess : public PropertyAccessBase {
|
||||
@ -1964,6 +1959,11 @@ class PropertyAccess : public PropertyAccessBase {
|
||||
MOZ_ASSERT_IF(match, node.is<PropertyAccessBase>());
|
||||
return match;
|
||||
}
|
||||
|
||||
bool isSuper() const {
|
||||
// ParseNodeKind::SuperBase cannot result from any expression syntax.
|
||||
return expression().isKind(ParseNodeKind::SuperBase);
|
||||
}
|
||||
};
|
||||
|
||||
class OptionalPropertyAccess : public PropertyAccessBase {
|
||||
@ -1999,8 +1999,6 @@ class PropertyByValueBase : public BinaryNode {
|
||||
ParseNode& expression() const { return *left(); }
|
||||
|
||||
ParseNode& key() const { return *right(); }
|
||||
|
||||
bool isSuper() const { return left()->isKind(ParseNodeKind::SuperBase); }
|
||||
};
|
||||
|
||||
class PropertyByValue : public PropertyByValueBase {
|
||||
@ -2015,6 +2013,8 @@ class PropertyByValue : public PropertyByValueBase {
|
||||
MOZ_ASSERT_IF(match, node.is<PropertyByValueBase>());
|
||||
return match;
|
||||
}
|
||||
|
||||
bool isSuper() const { return left()->isKind(ParseNodeKind::SuperBase); }
|
||||
};
|
||||
|
||||
class OptionalPropertyByValue : public PropertyByValueBase {
|
||||
|
@ -9445,6 +9445,7 @@ GeneralParser<ParseHandler, Unit>::memberPropertyAccess(
|
||||
}
|
||||
|
||||
if (optionalKind == OptionalKind::Optional) {
|
||||
MOZ_ASSERT(!handler_.isSuperBase(lhs));
|
||||
return handler_.newOptionalPropertyAccess(lhs, name);
|
||||
}
|
||||
return handler_.newPropertyAccess(lhs, name);
|
||||
@ -9469,6 +9470,7 @@ typename ParseHandler::Node GeneralParser<ParseHandler, Unit>::memberElemAccess(
|
||||
return null();
|
||||
}
|
||||
if (optionalKind == OptionalKind::Optional) {
|
||||
MOZ_ASSERT(!handler_.isSuperBase(lhs));
|
||||
return handler_.newOptionalPropertyByValue(lhs, propExpr, pos().end);
|
||||
}
|
||||
return handler_.newPropertyByValue(lhs, propExpr, pos().end);
|
||||
|
Loading…
Reference in New Issue
Block a user