Fix parsing of nested classes with private fields
The parsing of private fields checks whether or not it is within a class to determine if it is valid or not. However, the state.inClass property is incorrect as it marks it as outside a class when the inner class is closed. This commit fixes this problem by replacing the state.inClass property with a class nesting counter.
This commit is contained in:
parent
43dba7e7c1
commit
b4e06aa279
@ -684,7 +684,7 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
// class bodies are implicitly strict
|
// class bodies are implicitly strict
|
||||||
const oldStrict = this.state.strict;
|
const oldStrict = this.state.strict;
|
||||||
this.state.strict = true;
|
this.state.strict = true;
|
||||||
this.state.inClass = true;
|
this.state.classLevel++;
|
||||||
|
|
||||||
const state = { hadConstructor: false };
|
const state = { hadConstructor: false };
|
||||||
let decorators = [];
|
let decorators = [];
|
||||||
@ -731,7 +731,7 @@ export default class StatementParser extends ExpressionParser {
|
|||||||
|
|
||||||
node.body = this.finishNode(classBody, "ClassBody");
|
node.body = this.finishNode(classBody, "ClassBody");
|
||||||
|
|
||||||
this.state.inClass = false;
|
this.state.classLevel--;
|
||||||
this.state.strict = oldStrict;
|
this.state.strict = oldStrict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -444,7 +444,7 @@ export default class Tokenizer extends LocationParser {
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
||||||
case 35: // '#'
|
case 35: // '#'
|
||||||
if (this.hasPlugin("classPrivateProperties") && this.state.inClass) {
|
if (this.hasPlugin("classPrivateProperties") && this.state.classLevel > 0) {
|
||||||
++this.state.pos; return this.finishToken(tt.hash);
|
++this.state.pos; return this.finishToken(tt.hash);
|
||||||
} else {
|
} else {
|
||||||
this.raise(this.state.pos, `Unexpected character '${codePointToString(code)}'`);
|
this.raise(this.state.pos, `Unexpected character '${codePointToString(code)}'`);
|
||||||
|
|||||||
@ -24,11 +24,12 @@ export default class State {
|
|||||||
this.inAsync =
|
this.inAsync =
|
||||||
this.inPropertyName =
|
this.inPropertyName =
|
||||||
this.inType =
|
this.inType =
|
||||||
this.inClass =
|
|
||||||
this.inClassProperty =
|
this.inClassProperty =
|
||||||
this.noAnonFunctionType =
|
this.noAnonFunctionType =
|
||||||
false;
|
false;
|
||||||
|
|
||||||
|
this.classLevel = 0;
|
||||||
|
|
||||||
this.labels = [];
|
this.labels = [];
|
||||||
|
|
||||||
this.decorators = [];
|
this.decorators = [];
|
||||||
@ -84,7 +85,9 @@ export default class State {
|
|||||||
noAnonFunctionType: boolean;
|
noAnonFunctionType: boolean;
|
||||||
inPropertyName: boolean;
|
inPropertyName: boolean;
|
||||||
inClassProperty: boolean;
|
inClassProperty: boolean;
|
||||||
inClass: boolean;
|
|
||||||
|
// Check whether we are in a (nested) class or not.
|
||||||
|
classLevel: number;
|
||||||
|
|
||||||
// Labels in scope.
|
// Labels in scope.
|
||||||
labels: Array<{ kind: ?("loop" | "switch"), statementStart?: number }>;
|
labels: Array<{ kind: ?("loop" | "switch"), statementStart?: number }>;
|
||||||
|
|||||||
40
test/fixtures/experimental/class-private-properties/nested/actual.js
vendored
Normal file
40
test/fixtures/experimental/class-private-properties/nested/actual.js
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
class Point {
|
||||||
|
#x = 1;
|
||||||
|
#y = 2;
|
||||||
|
|
||||||
|
constructor(x = 0, y = 0) {
|
||||||
|
#x = +x;
|
||||||
|
#y = +y;
|
||||||
|
|
||||||
|
|
||||||
|
this.foo = class {
|
||||||
|
#x = 1;
|
||||||
|
#y = 2;
|
||||||
|
|
||||||
|
constructor(x = 0, y = 0) {
|
||||||
|
#x = +x;
|
||||||
|
#y = +y;
|
||||||
|
}
|
||||||
|
|
||||||
|
get x() { return #x }
|
||||||
|
set x(value) { #x = +value }
|
||||||
|
|
||||||
|
get y() { return #y }
|
||||||
|
set y(value) { #y = +value }
|
||||||
|
|
||||||
|
equals(p) { return #x === p.#x && #y === p.#y }
|
||||||
|
|
||||||
|
toString() { return `Point<${ #x },${ #y }>` }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get x() { return #x }
|
||||||
|
set x(value) { #x = +value }
|
||||||
|
|
||||||
|
get y() { return #y }
|
||||||
|
set y(value) { #y = +value }
|
||||||
|
|
||||||
|
equals(p) { return #x === p.#x && #y === p.#y }
|
||||||
|
|
||||||
|
toString() { return `Point<${ #x },${ #y }>` }
|
||||||
|
}
|
||||||
3353
test/fixtures/experimental/class-private-properties/nested/expected.json
vendored
Normal file
3353
test/fixtures/experimental/class-private-properties/nested/expected.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
test/fixtures/experimental/class-private-properties/nested/options.json
vendored
Normal file
3
test/fixtures/experimental/class-private-properties/nested/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["classProperties", "classPrivateProperties"]
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user