v8/test/inspector/debugger/get-possible-breakpoints-class-fields-expected.txt
Joyee Cheung 91f08378bc [class] implement reparsing of class instance member initializers
Previously, since the source code for the synthetic class instance
member initializer function was recorded as the span from the first
initializer to the last initializer, there was no way to reparse the
class and recompile the initializer function. It was working for
most use cases because the code for the initializer function was
generated eagarly and it was usually alive as long as the class was
alive, so the initializer wouldn't normally be lazily parsed. This
didn't work, however, when the class was snapshotted with
v8::SnapshotCreator::FunctionCodeHandling::kClear,
becuase then we needed to recompile the initializer when the class
was instantiated. This patch implements the reparsing so that
these classes can work with FunctionCodeHandling::kClear.

This patch refactors ParserBase::ParseClassLiteral() so that we can
reuse it for both parsing the class body normally and reparsing it
to collect initializers. When reparsing the synthetic initializer
function, we rewind the scanner to the beginning of the class, and
parse the class body to collect the initializers. During the
reparsing, field initializers are parsed with the full parser while
methods of the class are pre-parsed.

A few notable changes:

- Extended the source range of the initializer function to cover the
  entire class so that we can rewind the scanner to parse the class
  body to collect initializers (previously, it starts from the first
  field initializer and ends at the last initializer). This resulted
  some expectation changes in the debugger tests, though the
  initializers remain debuggable.
- A temporary ClassScope is created during reparsing. After the class
  is reparsed, we use the information from the ScopeInfo to update
  the allocated indices of the variables in the ClassScope.

Bug: v8:10704
Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#78299}
2021-12-08 14:41:56 +00:00

207 lines
2.8 KiB
Plaintext

Checks Debugger.getPossibleBreakpoints for class fields
// Copyright 2017 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.
let x = |R|class {}
|_|x = |R|class {
x = |_|1;
y = |_|2;
}|R|
|_|x = |R|class {
x = |C|foo();
y = |_|2;
z = |C|bar();
}|R|
|_|x = class {
x = |C|foo();
y = |_|2;
z = |C|bar();
constructor() {
this.|_|x;
|R|}
}|R|
|_|x = class {
x = |C|foo();
y = |_|2;
constructor() {
this.|_|x;
|R|}
z = |C|bar();
}|R|
|_|x = class {
x = |C|foo();
y = |_|2;
constructor() {
this.|_|x;
|R|}
z = |C|bar();
}|R|
|_|x = |R|class {
x = |_|1;
foo() {|R|}
y = |_|2;
}|R|
|_|x = |R|class {
x = (function() {
|C|foo();
|R|})|C|();
y = (() => {
|C|bar();
|R|})|C|();
}|R|
|_|x = |R|class {
x = |_|function() {
|C|foo();
|R|};
}|R|
|_|x = |R|class {
x = |_|async function() {
|_|await |C|foo();
|R|};
}|R|
|_|x = |R|class {
x = |_|() => {
|C|foo();
|R|};
y = |_|() => |C|bar()|R|;
}|R|
|_|x = |R|class {
x = |_|async () => {
|_|await |C|foo();
|R|};
y = |_|async () => |_|await |C|bar()|R|;
}|R|
|_|x = |R|class {
[|_|x] = |_|1;
[|C|foo()] = |_|2;
}|R|
|_|x = |R|class {
[|_|x] = |_|[...this];
}|R|
|_|x = |R|class {
x;
[|C|foo()];
}|R|
|_|x = |R|class {
x = |_|function*|_|() {
|_|yield 1;
|R|};
}|R|
|_|x = |R|class {
static x = |_|1;
static y = |_|2|R|;
}
|_|x = |R|class {
static x = |C|foo();
static y = |_|2;
static z = |C|bar()|R|;
}
|_|x = class {
static x = |C|foo();
static y = |_|2;
static z = |C|bar()|R|;
constructor() {
this.|_|x;
|R|}
}
|_|x = class {
static x = |C|foo();
static y = |_|2;
constructor() {
this.|_|x;
|R|}
static z = |C|bar()|R|;
}
|_|x = |R|class {
static x = |_|1;
static foo() {|R|}
bar() {|R|}
static y = |_|2|R|;
}
|_|x = |R|class {
static x = (function() {
|C|foo();
|R|})|C|();
static y = (() => {
|C|bar();
|R|})|C|()|R|;
}
|_|x = |R|class {
static x = |_|function() {
|C|foo();
|R|}|R|;
}
|_|x = |R|class {
static x = |_|async function() {
|_|await |C|foo();
|R|}|R|;
}
|_|x = |R|class {
static x = |_|() => {
|C|foo();
|R|};
static y = |_|() => |C|bar()|R|;
}
|_|x = |R|class {
static x = |_|async () => {
|_|await |C|foo();
|R|};
static y = |_|async () => |_|await |C|bar()|R|;
}
|_|x = |R|class {
static [|_|x] = |_|1;
static [|C|foo()] = |_|2|R|;
}
|_|x = |R|class {
static [|_|x] = |_|[...this]|R|;
}
|_|x = |R|class {
static x;
static [|C|foo()]|R|;
}
|_|x = |R|class {
static x = |_|function*|_|() {
|_|yield 1;
|R|}|R|;
}
|_|x = |R|class {
static x = |_|1;
y = |_|2;
static [|_|z] = |_|3;
[|_|p] = |_|4;
static [|C|foo()] = |_|5|R|;
[|C|bar()] = |_|6;
}|R|
|R|