Commit 3da7cd36 authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[class] Allow CallExpressions to access private fields

Bug: v8:5368
Change-Id: I92874d5ea190cd892f3cb5216e0f4bb5373d5350
Reviewed-on: https://chromium-review.googlesource.com/927345Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51436}
parent c933b65d
...@@ -1088,6 +1088,8 @@ class ParserBase { ...@@ -1088,6 +1088,8 @@ class ParserBase {
IdentifierT ParseIdentifierName(bool* ok); IdentifierT ParseIdentifierName(bool* ok);
ExpressionT ParseIdentifierNameOrPrivateName(bool* ok);
ExpressionT ParseRegExpLiteral(bool* ok); ExpressionT ParseRegExpLiteral(bool* ok);
ExpressionT ParsePrimaryExpression(bool* is_async, bool* ok); ExpressionT ParsePrimaryExpression(bool* is_async, bool* ok);
...@@ -1787,6 +1789,27 @@ typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName( ...@@ -1787,6 +1789,27 @@ typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName(
return impl()->GetSymbol(); return impl()->GetSymbol();
} }
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseIdentifierNameOrPrivateName(bool* ok) {
int pos = position();
IdentifierT name;
ExpressionT key;
if (allow_harmony_private_fields() && peek() == Token::PRIVATE_NAME) {
Consume(Token::PRIVATE_NAME);
name = impl()->GetSymbol();
auto key_proxy =
impl()->ExpressionFromIdentifier(name, pos, InferName::kNo);
key_proxy->set_is_private_field();
key = key_proxy;
} else {
name = ParseIdentifierName(CHECK_OK);
key = factory()->NewStringLiteral(name, pos);
}
impl()->PushLiteralName(name);
return key;
}
template <typename Impl> template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral( typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral(
bool* ok) { bool* ok) {
...@@ -3420,10 +3443,8 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) { ...@@ -3420,10 +3443,8 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
ArrowFormalParametersUnexpectedToken(); ArrowFormalParametersUnexpectedToken();
Consume(Token::PERIOD); Consume(Token::PERIOD);
int pos = position(); int pos = position();
IdentifierT name = ParseIdentifierName(CHECK_OK); ExpressionT key = ParseIdentifierNameOrPrivateName(CHECK_OK);
result = factory()->NewProperty( result = factory()->NewProperty(result, key, pos);
result, factory()->NewStringLiteral(name, pos), pos);
impl()->PushLiteralName(name);
break; break;
} }
...@@ -3720,21 +3741,8 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression, ...@@ -3720,21 +3741,8 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
Consume(Token::PERIOD); Consume(Token::PERIOD);
int pos = peek_position(); int pos = peek_position();
ExpressionT key; ExpressionT key = ParseIdentifierNameOrPrivateName(CHECK_OK);
IdentifierT name;
if (allow_harmony_private_fields() && peek() == Token::PRIVATE_NAME) {
Consume(Token::PRIVATE_NAME);
name = impl()->GetSymbol();
auto key_proxy =
impl()->ExpressionFromIdentifier(name, pos, InferName::kNo);
key_proxy->set_is_private_field();
key = key_proxy;
} else {
name = ParseIdentifierName(CHECK_OK);
key = factory()->NewStringLiteral(name, pos);
}
expression = factory()->NewProperty(expression, key, pos); expression = factory()->NewProperty(expression, key, pos);
impl()->PushLiteralName(name);
break; break;
} }
case Token::TEMPLATE_SPAN: case Token::TEMPLATE_SPAN:
......
...@@ -5089,6 +5089,16 @@ TEST(PrivateNameNoErrors) { ...@@ -5089,6 +5089,16 @@ TEST(PrivateNameNoErrors) {
"foo.#b.#a", "foo.#b.#a",
"foo.#b.#a()", "foo.#b.#a()",
"foo().#a",
"foo().b.#a",
"foo().b().#a",
"foo().b().#a()",
"foo().b().#a.bar",
"foo().b().#a.bar()",
"foo(this.#a)",
"foo(bar().#a)",
"new foo.#a", "new foo.#a",
"new foo.#b.#a", "new foo.#b.#a",
"new foo.#b.#a()", "new foo.#b.#a()",
......
...@@ -353,3 +353,27 @@ ...@@ -353,3 +353,27 @@
//assertThrows(() => p.getA(), ReferenceError); //assertThrows(() => p.getA(), ReferenceError);
assertEquals(1, p[symbol]); assertEquals(1, p[symbol]);
} }
{
class C {
#a = 1;
b;
getA() { return this.b().#a; }
}
let c = new C();
c.b = () => c;
assertEquals(1, c.getA());
}
{
class C {
#a = 1;
b;
getA(arg) { return arg.b().#a; }
}
let c = new C();
c.b = () => c;
assertEquals(1, c.getA(c));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment