Skip to content

Commit

Permalink
Merge pull request #18 from lxsmnsyc/next
Browse files Browse the repository at this point in the history
Add `$getter`, `$setter` and `$property` auto-prototype
  • Loading branch information
lxsmnsyc authored Oct 23, 2023
2 parents 2ef61b0 + f352a92 commit e8483be
Show file tree
Hide file tree
Showing 10 changed files with 587 additions and 250 deletions.
52 changes: 27 additions & 25 deletions docs/ctf.md
Original file line number Diff line number Diff line change
Expand Up @@ -938,14 +938,15 @@ const obj = {

```js
import { createSignal as _createSignal } from "solid-js";
let [_count, _setcount] = _createSignal(0);
const obj = {
const _proto = {
get count() {
return _count();
return this.__$get$count();
}
};
let [_count, _setcount] = _createSignal(0);
const obj = {
__proto__: _proto,
__$get$count: _count
};
```

Expand All @@ -963,14 +964,15 @@ const obj = {

```js
import { createSignal as _createSignal } from "solid-js";
const _proto = {
set count(_param) {
this.__$set$count(() => _param);
}
};
let [_count, _setcount] = _createSignal(0);
const obj = {
set count(_value) {
return _setcount(() => _value);
}
__proto__: _proto,
__$set$count: _setcount
};
```

Expand All @@ -991,24 +993,24 @@ const obj = {
```js
import { createMemo as _createMemo } from "solid-js";
import { createSignal as _createSignal } from "solid-js";
let [_count, _setcount] = _createSignal(0);
const _message = _createMemo(() => `Count: ${_count()}`);
const obj = {
const _proto = {
get count() {
return _count();
return this.__$get$count();
},
set count(_value) {
return _setcount(() => _value);
set count(_param) {
this.__$set$count(() => _param);
},
get message() {
return _message();
return this.__$get$message();
}
};
let [_count, _setcount] = _createSignal(0);
const _message = _createMemo(() => `Count: ${_count()}`);
const obj = {
__proto__: _proto,
__$get$count: _count,
__$set$count: _setcount,
__$get$message: _message
};
```

Expand Down
20 changes: 9 additions & 11 deletions packages/babel/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,14 @@ async function compile(code, dev) {
}

console.log(await compile(`
// @destructure
let { a: { b, c }, b: { d, e }, ...f } = x;
let foo = $signal('foo');
let bar = $signal('bar')
effect: {
console.log(b, c);
}
effect: {
console.log(d, e);
}
effect: {
console.log(f);
}
const example = {
foo: $property(foo),
bar: $property(bar),
baz: baz,
};
$(console.log(example.foo, example.bar));
`));
80 changes: 38 additions & 42 deletions packages/babel/src/core/deref-memo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as t from '@babel/types';
import assert from './assert';
import { unexpectedType } from './errors';
import unwrapNode from './unwrap-node';
import { addProtoGetter } from './proto';

const REF_MEMO_CTF = '$refMemo';
const GET_CTF = '$get';
Expand All @@ -14,18 +15,23 @@ const PROPERTY_CTF = '$property';

const OBJECT_PROPERTY_CTF = new Set([GETTER_CTF, PROPERTY_CTF]);

interface DerefMemoState {
current?: babel.NodePath<t.ObjectExpression>;
prev?: babel.NodePath<t.ObjectExpression>;
}

export default function derefMemo(
path: babel.NodePath,
memoIdentifier: t.Identifier,
readIdentifier: t.Identifier,
): void {
path.scope.path.traverse({
path.scope.path.traverse<DerefMemoState>({
CallExpression(p) {
if (p.scope !== path.scope && p.scope.hasOwnBinding(memoIdentifier.name)) {
return;
}
const trueCallee = unwrapNode(p.node.callee, t.isIdentifier);
if (!trueCallee || p.scope.hasBinding(trueCallee.name) || !CALL_CTF.has(trueCallee.name)) {
if (!trueCallee || !CALL_CTF.has(trueCallee.name)) {
return;
}
const rawArgs = p.node.arguments[0];
Expand All @@ -41,27 +47,38 @@ export default function derefMemo(
p.replaceWith(readIdentifier);
}
},
ObjectExpression: {
enter(p) {
this.prev = this.current;
this.current = p;
},
exit() {
this.current = this.prev;
},
},
ObjectProperty(p) {
if (p.scope !== path.scope && p.scope.hasOwnBinding(memoIdentifier.name)) {
return;
}
const currentValue = p.node.value;
const currentKey = p.node.key;
if (p.node.shorthand && !p.node.computed) {
if (
t.isIdentifier(p.node.key)
&& t.isIdentifier(p.node.value)
&& p.node.key.name === memoIdentifier.name
&& p.node.value.name === memoIdentifier.name
t.isIdentifier(currentKey)
&& t.isIdentifier(currentValue)
&& currentKey.name === memoIdentifier.name
&& currentValue.name === memoIdentifier.name
) {
p.replaceWith(
t.objectProperty(
p.node.key,
currentKey,
t.callExpression(readIdentifier, []),
),
);
}
return;
}
const trueCallExpr = unwrapNode(p.node.value, t.isCallExpression);
const trueCallExpr = unwrapNode(currentValue, t.isCallExpression);
if (trueCallExpr) {
const trueCallee = unwrapNode(trueCallExpr.callee, t.isIdentifier);
if (
Expand All @@ -71,45 +88,21 @@ export default function derefMemo(
) {
return;
}
assert(!t.isPrivateName(p.node.key), unexpectedType(p, 'PrivateName', 'Expression'));
assert(!t.isPrivateName(currentKey), unexpectedType(p, 'PrivateName', 'Expression'));
const arg = trueCallExpr.arguments[0];
assert(t.isIdentifier(arg), unexpectedType(p, arg.type, 'Identifier'));
if (arg.name !== memoIdentifier.name) {
return;
}
if (trueCallee.name === GETTER_CTF) {
p.replaceWith(
t.objectMethod(
'get',
p.node.key,
[],
t.blockStatement([
t.returnStatement(
t.callExpression(
readIdentifier,
[],
),
),
]),
),
);
}
if (trueCallee.name === PROPERTY_CTF) {
p.replaceWith(
t.objectMethod(
'get',
p.node.key,
[],
t.blockStatement([
t.returnStatement(
t.callExpression(
readIdentifier,
[],
),
),
]),
),
);
if (this.current) {
switch (trueCallee.name) {
case GETTER_CTF:
case PROPERTY_CTF:
addProtoGetter(this.current, p, currentKey, readIdentifier);
break;
default:
break;
}
}
}
},
Expand All @@ -125,5 +118,8 @@ export default function derefMemo(
p.replaceWith(t.callExpression(readIdentifier, []));
}
},
}, {
current: undefined,
prev: undefined,
});
}
Loading

0 comments on commit e8483be

Please sign in to comment.