[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:
parent
275239382e
commit
ad988c6964
@ -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, \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
6
test/message/fail/class-fields-private-outside-class.js
Normal file
6
test/message/fail/class-fields-private-outside-class.js
Normal 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;
|
4
test/message/fail/class-fields-private-outside-class.out
Normal file
4
test/message/fail/class-fields-private-outside-class.out
Normal 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
|
@ -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
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user