Skip to content

Commit

Permalink
Adds the accessor modifier to public and private class properties.
Browse files Browse the repository at this point in the history
This is the first part of the implementation of the latest version of
the decorators proposal: https://github.com/tc39/proposal-decorators

The keyword is outlined here in the README: https://github.com/tc39/proposal-decorators#class-auto-accessors
  • Loading branch information
pzuraq committed Aug 16, 2021
1 parent d3a7cd5 commit 95d5837
Show file tree
Hide file tree
Showing 14 changed files with 253 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/babel-parser/ast/spec.md
Expand Up @@ -1235,6 +1235,7 @@ interface ClassProperty <: Node {
value: Expression;
static: boolean;
computed: boolean;
accessor: boolean;
}
```

Expand Down
40 changes: 38 additions & 2 deletions packages/babel-parser/src/parser/statement.js
Expand Up @@ -1373,6 +1373,14 @@ export default class StatementParser extends ExpressionParser {
prop.computed = false;
prop.key = key;
prop.static = false;
if (
this.hasPlugin("decorators") &&
this.getPluginOption("decorators", "version") === "modern"
) {
prop.accessor = false;
}
classBody.body.push(this.parseClassProperty(prop));
return true;
}
Expand Down Expand Up @@ -1409,10 +1417,11 @@ export default class StatementParser extends ExpressionParser {
) {
const publicMethod: $FlowSubtype<N.ClassMethod> = member;
const privateMethod: $FlowSubtype<N.ClassPrivateMethod> = member;
const publicProp: $FlowSubtype<N.ClassMethod> = member;
const privateProp: $FlowSubtype<N.ClassPrivateMethod> = member;
const publicProp: $FlowSubtype<N.ClassProperty> = member;
const privateProp: $FlowSubtype<N.ClassPrivateProperty> = member;
const method: typeof publicMethod | typeof privateMethod = publicMethod;
const prop: typeof publicProp | typeof privateProp = publicProp;
const publicMember: typeof publicMethod | typeof publicProp = publicMethod;
member.static = isStatic;
Expand Down Expand Up @@ -1486,6 +1495,13 @@ export default class StatementParser extends ExpressionParser {
allowsDirectSuper,
);
} else if (this.isClassProperty()) {
if (
this.hasPlugin("decorators") &&
this.getPluginOption("decorators", "version") === "modern"
) {
prop.accessor = false;
}
if (isPrivate) {
this.pushClassPrivateProperty(classBody, privateProp);
} else {
Expand Down Expand Up @@ -1563,6 +1579,26 @@ export default class StatementParser extends ExpressionParser {
}

this.checkGetterSetterParams(publicMethod);
} else if (
isContextual &&
key.name === "accessor" &&
this.hasPlugin("decorators") &&
this.getPluginOption("decorators", "version") === "modern" &&
!this.isLineTerminator()
) {
this.resetPreviousNodeTrailingComments(key);

// The so-called parsed name would have been "get/set": get the real name.
const isPrivate = this.match(tt.privateName);
this.parseClassElementName(publicProp);

prop.accessor = true;

if (isPrivate) {
this.pushClassPrivateProperty(classBody, privateProp);
} else {
this.pushClassProperty(classBody, publicProp);
}
} else if (this.isLineTerminator()) {
// an uninitialized class property (due to ASI, since we don't otherwise recognize the next token)
if (isPrivate) {
Expand Down
2 changes: 2 additions & 0 deletions packages/babel-parser/src/types.js
Expand Up @@ -813,6 +813,7 @@ export type ClassProperty = ClassMemberBase &
type: "ClassProperty",
key: Expression,
value: ?Expression, // TODO: Not in spec that this is nullable.
accessor?: boolean, // Decorators proposal

typeAnnotation?: ?TypeAnnotationBase, // TODO: Not in spec
variance?: ?FlowVariance, // TODO: Not in spec
Expand All @@ -828,6 +829,7 @@ export type ClassPrivateProperty = NodeBase & {
value: ?Expression, // TODO: Not in spec that this is nullable.
static: boolean,
computed: false,
accessor?: boolean, // Decorators proposal

// Flow and Typescript
typeAnnotation?: ?TypeAnnotationBase,
Expand Down
@@ -0,0 +1,3 @@
class Foo {
accessor bar;
}
@@ -0,0 +1,42 @@
{
"type": "File",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"program": {
"type": "Program",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":29,"loc":{"start":{"line":1,"column":10},"end":{"line":3,"column":1}},
"body": [
{
"type": "ClassProperty",
"start":14,"end":27,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":15}},
"static": false,
"key": {
"type": "Identifier",
"start":23,"end":26,"loc":{"start":{"line":2,"column":11},"end":{"line":2,"column":14},"identifierName":"bar"},
"name": "bar"
},
"computed": false,
"accessor": true,
"value": null
}
]
}
}
],
"directives": []
}
}
@@ -0,0 +1,3 @@
class Foo {
accessor = 123;
}
@@ -0,0 +1,50 @@
{
"type": "File",
"start":0,"end":31,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"program": {
"type": "Program",
"start":0,"end":31,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":31,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":31,"loc":{"start":{"line":1,"column":10},"end":{"line":3,"column":1}},
"body": [
{
"type": "ClassProperty",
"start":14,"end":29,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":17}},
"static": false,
"key": {
"type": "Identifier",
"start":14,"end":22,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":10},"identifierName":"accessor"},
"name": "accessor"
},
"computed": false,
"accessor": false,
"value": {
"type": "NumericLiteral",
"start":25,"end":28,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":16}},
"extra": {
"rawValue": 123,
"raw": "123"
},
"value": 123
}
}
]
}
}
],
"directives": []
}
}
@@ -0,0 +1,3 @@
class Foo {
accessor() {}
}
@@ -0,0 +1,51 @@
{
"type": "File",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"program": {
"type": "Program",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":29,"loc":{"start":{"line":1,"column":10},"end":{"line":3,"column":1}},
"body": [
{
"type": "ClassMethod",
"start":14,"end":27,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":15}},
"static": false,
"key": {
"type": "Identifier",
"start":14,"end":22,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":10},"identifierName":"accessor"},
"name": "accessor"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":25,"end":27,"loc":{"start":{"line":2,"column":13},"end":{"line":2,"column":15}},
"body": [],
"directives": []
}
}
]
}
}
],
"directives": []
}
}
@@ -0,0 +1,5 @@
class Foo {
accessor bar() {

}
}
@@ -0,0 +1,3 @@
{
"throws": "Unexpected token (2:14)"
}
@@ -0,0 +1,3 @@
class Foo {
accessor #bar;
}
@@ -0,0 +1,46 @@
{
"type": "File",
"start":0,"end":30,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"program": {
"type": "Program",
"start":0,"end":30,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":30,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":30,"loc":{"start":{"line":1,"column":10},"end":{"line":3,"column":1}},
"body": [
{
"type": "ClassPrivateProperty",
"start":14,"end":28,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":16}},
"static": false,
"key": {
"type": "PrivateName",
"start":23,"end":27,"loc":{"start":{"line":2,"column":11},"end":{"line":2,"column":15}},
"id": {
"type": "Identifier",
"start":24,"end":27,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":15},"identifierName":"bar"},
"name": "bar"
}
},
"computed": false,
"accessor": true,
"value": null
}
]
}
}
],
"directives": []
}
}
@@ -0,0 +1,3 @@
{
"plugins": [["decorators", { "decoratorsBeforeExport": false, "version": "modern" }]]
}

0 comments on commit 95d5837

Please sign in to comment.