[parser] fix name and position when reporting private field outside of classes

Bug: v8:8578
Change-Id: If6b62b7d0ca2be03ab46c58d33aa2353ddd44986
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1584251
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61318}
This commit is contained in:
Joyee Cheung 2019-05-01 13:52:40 +08:00 committed by Commit Bot
parent 275239382e
commit ad988c6964
12 changed files with 50 additions and 15 deletions

View File

@ -398,7 +398,7 @@ namespace internal {
T(InvalidRegExpFlags, "Invalid flags supplied to RegExp constructor '%'") \
T(InvalidOrUnexpectedToken, "Invalid or unexpected token") \
T(InvalidPrivateFieldResolution, \
"Undefined private field %: must be declared in an enclosing class") \
"Private field '%' must be declared in an enclosing class") \
T(InvalidPrivateFieldRead, \
"Read of private field % from an object which did not contain the field") \
T(InvalidPrivateFieldWrite, \

View File

@ -1559,16 +1559,16 @@ ParserBase<Impl>::ParsePropertyOrPrivatePropertyName() {
//
// Here, we check if this is a new private name reference in a top
// level function and throw an error if so.
//
// Bug(v8:7468): This hack will go away once we refactor private
// name resolution to happen independently from scope resolution.
ClassScope* class_scope = scope()->GetClassScope();
// Parse the identifier so that we can display it in the error message
name = impl()->GetIdentifier();
if (class_scope == nullptr) {
ReportMessage(MessageTemplate::kInvalidPrivateFieldResolution);
impl()->ReportMessageAt(Scanner::Location(pos, pos + 1),
MessageTemplate::kInvalidPrivateFieldResolution,
impl()->GetRawNameFromIdentifier(name),
kSyntaxError);
return impl()->FailureExpression();
}
name = impl()->GetIdentifier();
key = impl()->ExpressionFromPrivateName(class_scope, name, pos);
} else {
ReportUnexpectedToken(next);

View File

@ -698,6 +698,10 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
scanner_.set_parser_error();
}
const AstRawString* GetRawNameFromIdentifier(const AstRawString* arg) {
return arg;
}
void ReportUnexpectedTokenAt(
Scanner::Location location, Token::Value token,
MessageTemplate message = MessageTemplate::kUnexpectedToken);

View File

@ -1505,6 +1505,10 @@ class PreParser : public ParserBase<PreParser> {
scanner()->set_parser_error();
}
const AstRawString* GetRawNameFromIdentifier(const PreParserIdentifier& arg) {
return arg.string_;
}
// "null" return type creators.
V8_INLINE static PreParserIdentifier NullIdentifier() {
return PreParserIdentifier::Null();

View File

@ -1,4 +1,4 @@
*%(basename)s:10: SyntaxError: Undefined private field #b: must be declared in an enclosing class
*%(basename)s:10: SyntaxError: Private field '#b' must be declared in an enclosing class
getB() { return this.#b; }
^
SyntaxError: Undefined private field #b: must be declared in an enclosing class
SyntaxError: Private field '#b' must be declared in an enclosing class

View File

@ -0,0 +1,6 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class Foo { #x = 42; }
new Foo().#x;

View File

@ -0,0 +1,4 @@
*%(basename)s:6: SyntaxError: Private field '#x' must be declared in an enclosing class
new Foo().#x;
^
SyntaxError: Private field '#x' must be declared in an enclosing class

View File

@ -1,4 +1,4 @@
*%(basename)s:7: SyntaxError: Undefined private field #x: must be declared in an enclosing class
*%(basename)s:7: SyntaxError: Private field '#x' must be declared in an enclosing class
this.#x = 1;
^
SyntaxError: Undefined private field #x: must be declared in an enclosing class
SyntaxError: Private field '#x' must be declared in an enclosing class

View File

@ -1,4 +1,4 @@
*%(basename)s:9: SyntaxError: Undefined private field #x: must be declared in an enclosing class
*%(basename)s:9: SyntaxError: Private field '#x' must be declared in an enclosing class
this.#x = 1;
^
SyntaxError: Undefined private field #x: must be declared in an enclosing class
SyntaxError: Private field '#x' must be declared in an enclosing class

View File

@ -0,0 +1,13 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function x() {
class Foo {
constructor () {
class Bar {
x = this.#foo;
}
}
}
}

View File

@ -0,0 +1,4 @@
*%(basename)s:9: SyntaxError: Private field '#foo' must be declared in an enclosing class
x = this.#foo;
^
SyntaxError: Private field '#foo' must be declared in an enclosing class

View File

@ -1,4 +1,4 @@
*%(basename)s:8: SyntaxError: Undefined private field #b: must be declared in an enclosing class
*%(basename)s:8: SyntaxError: Private field '#b' must be declared in an enclosing class
getA() { return this.#b; }
^
SyntaxError: Undefined private field #b: must be declared in an enclosing class
SyntaxError: Private field '#b' must be declared in an enclosing class