Skip to content

Commit

Permalink
feat: implement proposal-class-static-block
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Oct 6, 2020
1 parent 51ff2e7 commit 4ce6931
Show file tree
Hide file tree
Showing 22 changed files with 252 additions and 1 deletion.
3 changes: 3 additions & 0 deletions packages/babel-plugin-proposal-class-static-block/.npmignore
@@ -0,0 +1,3 @@
src
test
*.log
19 changes: 19 additions & 0 deletions packages/babel-plugin-proposal-class-static-block/README.md
@@ -0,0 +1,19 @@
# @babel/plugin-proposal-class-static-block

> Allow transforming of class static blocks
See our website [@babel/plugin-proposal-class-static-block](https://babeljs.io/docs/en/next/babel-plugin-proposal-class-static-block.html) for more information.

## Install

Using npm:

```sh
npm install --save-dev @babel/plugin-proposal-class-static-block
```

or using yarn:

```sh
yarn add @babel/plugin-proposal-class-static-block --dev
```
28 changes: 28 additions & 0 deletions packages/babel-plugin-proposal-class-static-block/package.json
@@ -0,0 +1,28 @@
{
"name": "@babel/plugin-proposal-class-static-block",
"version": "7.11.0",
"description": "Allow parsing of class static blocks",
"repository": {
"type": "git",
"url": "https://github.com/babel/babel.git",
"directory": "packages/babel-plugin-proposal-class-static-block"
},
"license": "MIT",
"publishConfig": {
"access": "public"
},
"main": "./lib/index.js",
"exports": {
".": "./lib/index.js"
},
"keywords": [
"babel-plugin"
],
"dependencies": {
"@babel/helper-plugin-utils": "workspace:^7.10.1",
"@babel/plugin-syntax-class-static-block": "workspace:^7.11.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
}
52 changes: 52 additions & 0 deletions packages/babel-plugin-proposal-class-static-block/src/index.js
@@ -0,0 +1,52 @@
import { declare } from "@babel/helper-plugin-utils";
import syntaxClassStaticBlock from "@babel/plugin-syntax-class-static-block";

export default declare(({ types: t, template, assertVersion }) => {
assertVersion(7);

return {
name: "proposal-class-static-block",
inherits: syntaxClassStaticBlock,
visitor: {
StaticBlock(path) {
const staticBlockRef = path.scope.generateUidIdentifier("init");
const classPath = path.parentPath.parentPath;
path.replaceWith(
t.classMethod(
"method",
staticBlockRef,
[],
t.BlockStatement(
// Add completion record. A static block can not contain directly
// `return`, `break`, `continue`. So `return this` must be executed.
path.node.body.concat([
template.ast`delete this.${t.cloneNode(staticBlockRef)};`,
template.ast`return this;`,
]),
),
/* computed */ false,
/* static */ true,
),
);
const classId = classPath.node.id;
if (!classId) {
// If `classId` is not defined, we don't have to preserve the class binding
// `class { }` transformed as `(class { })._init()`
classPath.replaceWith(
template.ast`(${classPath.node}).${t.cloneNode(staticBlockRef)}()`,
);
} else {
// If `classId` is defined, preserve the class binding.
// `class Foo { }` transformed as `(Foo = (class Foo { })._init())`
classPath.node.type = "ClassExpression";
classPath.replaceWith(
template.ast`${t.cloneNode(classId)} = (${
classPath.node
}).${t.cloneNode(staticBlockRef)}()`,
);
classPath.insertBefore(template.ast`let ${t.cloneNode(classId)};`);
}
},
},
};
});
@@ -0,0 +1,6 @@
class Foo {
static {
this.foo = 42;
}
}
expect(Foo.foo).toBe(42);
@@ -0,0 +1,6 @@
class Foo {
static {
this.foo = 42;
}
}
expect(Foo.foo).toBe(42);
@@ -0,0 +1,10 @@
let Foo;
Foo = class Foo {
static _init() {
this.foo = 42;
delete this._init;
return this;
}

}._init();
expect(Foo.foo).toBe(42);
@@ -0,0 +1,6 @@
class Foo {
static {
this.foo = 42;
}
}
expect(Foo.foo).toBe(42);
@@ -0,0 +1,3 @@
{
"plugins": ["proposal-class-static-block", "syntax-class-properties"]
}
@@ -0,0 +1,10 @@
class Foo extends class {
static {
this.bar = 21;
}
} {
static {
this.foo = 2 * this.bar;
}
}
expect(Foo.foo).toBe(42);
@@ -0,0 +1,10 @@
class Foo extends class Bar {
static {
this.bar = 21;
}
} {
static {
this.foo = 2 * this.bar;
}
}
expect(Foo.foo).toBe(42);
@@ -0,0 +1,18 @@
let Foo;
let Bar;
Foo = class Foo extends (Bar = class Bar {
static _init2() {
this.bar = 21;
delete this._init2;
return this;
}

}._init2()) {
static _init() {
this.foo = 2 * this.bar;
delete this._init;
return this;
}

}._init();
expect(Foo.foo).toBe(42);
@@ -0,0 +1,10 @@
class Foo extends class {
static {
this.bar = 21;
}
} {
static {
this.foo = 2 * this.bar;
}
}
expect(Foo.foo).toBe(42);
@@ -0,0 +1,10 @@
class Foo extends class {
static {
this.bar = 21;
}
} {
static {
this.foo = 2 * this.bar;
}
}
expect(Foo.foo).toBe(42);
@@ -0,0 +1,17 @@
let Foo;
Foo = class Foo extends class {
static _init2() {
this.bar = 21;
delete this._init2;
return this;
}

}._init2() {
static _init() {
this.foo = 2 * this.bar;
delete this._init;
return this;
}

}._init();
expect(Foo.foo).toBe(42);
@@ -0,0 +1,8 @@
let getFoo;
class Foo {
static #foo = 42;
static {
getFoo = () => this.#foo;
}
}
expect(getFoo()).toBe(42);
@@ -0,0 +1,4 @@
{
"plugins": ["proposal-class-static-block", "syntax-class-properties"],
"minNodeVersion": "12.0.0"
}
@@ -0,0 +1,11 @@
class Foo extends class {
static {
this.bar = 42;
}
} {
static bar = 21;
static {
this.foo = super.bar;
}
}
expect(Foo.foo).toBe(42);
@@ -0,0 +1,3 @@
{
"plugins": ["proposal-class-static-block", "syntax-class-properties"]
}
@@ -0,0 +1,3 @@
{
"plugins": ["proposal-class-static-block"]
}
@@ -0,0 +1,3 @@
import runner from "@babel/helper-plugin-test-runner";

runner(__dirname);
13 changes: 12 additions & 1 deletion yarn.lock
Expand Up @@ -1004,6 +1004,17 @@ __metadata:
languageName: unknown
linkType: soft

"@babel/plugin-proposal-class-static-block@workspace:packages/babel-plugin-proposal-class-static-block":
version: 0.0.0-use.local
resolution: "@babel/plugin-proposal-class-static-block@workspace:packages/babel-plugin-proposal-class-static-block"
dependencies:
"@babel/helper-plugin-utils": "workspace:^7.10.1"
"@babel/plugin-syntax-class-static-block": "workspace:^7.11.0"
peerDependencies:
"@babel/core": ^7.0.0-0
languageName: unknown
linkType: soft

"@babel/plugin-proposal-decorators@workspace:^7.10.4, @babel/plugin-proposal-decorators@workspace:^7.10.5, @babel/plugin-proposal-decorators@workspace:packages/babel-plugin-proposal-decorators":
version: 0.0.0-use.local
resolution: "@babel/plugin-proposal-decorators@workspace:packages/babel-plugin-proposal-decorators"
Expand Down Expand Up @@ -1449,7 +1460,7 @@ __metadata:
languageName: unknown
linkType: soft

"@babel/plugin-syntax-class-static-block@workspace:packages/babel-plugin-syntax-class-static-block":
"@babel/plugin-syntax-class-static-block@workspace:^7.11.0, @babel/plugin-syntax-class-static-block@workspace:packages/babel-plugin-syntax-class-static-block":
version: 0.0.0-use.local
resolution: "@babel/plugin-syntax-class-static-block@workspace:packages/babel-plugin-syntax-class-static-block"
dependencies:
Expand Down

0 comments on commit 4ce6931

Please sign in to comment.