Skip to content

Commit dda45be

Browse files
committed
refactor: refactor-only avoid symbol-named methods
1 parent 37d948e commit dda45be

17 files changed

+113
-75
lines changed

packages/daemon/src/reader-ref.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ export const makeIteratorRef = iterable => {
6060
}
6161
return harden({ done: true, value: undefined });
6262
},
63-
[Symbol.asyncIterator]() {
64-
return this;
65-
},
6663
});
6764
};
6865

packages/daemon/src/ref-reader.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@ import { E } from '@endo/far';
1111
* @param {import('@endo/far').ERef<AsyncIterator<TValue, TReturn, TNext>>} iteratorRef
1212
*/
1313
export const makeRefIterator = iteratorRef => {
14-
const iterator = {
14+
const iterator = harden({
1515
/** @param {[] | [TNext]} args */
1616
next: async (...args) => E(iteratorRef).next(...args),
1717
/** @param {[] | [TReturn]} args */
1818
return: async (...args) => E(iteratorRef).return(...args),
1919
/** @param {any} error */
2020
throw: async error => E(iteratorRef).throw(error),
2121
[Symbol.asyncIterator]: () => iterator,
22-
};
22+
});
2323
return iterator;
2424
};
25+
harden(makeRefIterator);
2526

2627
/**
2728
* @param {import('@endo/far').ERef<AsyncIterator<string>>} readerRef

packages/exo/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
},
4444
"devDependencies": {
4545
"@endo/init": "workspace:^",
46+
"@endo/marshal": "workspace:^",
4647
"@endo/ses-ava": "workspace:^",
4748
"ava": "^6.1.3",
4849
"babel-eslint": "^10.1.0",

packages/exo/src/exo-tools.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import { getMethodNames } from '@endo/eventual-send/utils.js';
2-
import { hasOwnPropertyOf, toThrowable } from '@endo/pass-style';
3-
import { E, Far } from '@endo/far';
1+
import { E } from '@endo/eventual-send';
2+
import {
3+
getRemotableMethodNames,
4+
hasOwnPropertyOf,
5+
toThrowable,
6+
Far,
7+
} from '@endo/pass-style';
48
import {
59
mustMatch,
610
M,
@@ -17,8 +21,10 @@ import { q, Fail } from '@endo/errors';
1721
import { GET_INTERFACE_GUARD } from './get-interface.js';
1822

1923
/**
20-
* @import {InterfaceGuard, Method, MethodGuard, MethodGuardPayload} from '@endo/patterns'
24+
* @import {RemotableMethodName} from '@endo/pass-style';
25+
* @import {InterfaceGuard, Method, MethodGuard, MethodGuardPayload, DefaultGuardType} from '@endo/patterns'
2126
* @import {ClassContext, ContextProvider, FacetName, KitContext, KitContextProvider, MatchConfig, Methods} from './types.js'
27+
* @import {GetInterfaceGuard} from './get-interface.js';
2228
*/
2329

2430
const { apply, ownKeys } = Reflect;
@@ -344,7 +350,7 @@ const bindMethod = (
344350
};
345351

346352
/**
347-
* @template {Record<PropertyKey, CallableFunction>} T
353+
* @template {Record<RemotableMethodName, CallableFunction>} T
348354
* @param {string} tag
349355
* @param {ContextProvider} contextProvider
350356
* @param {T} behaviorMethods
@@ -359,7 +365,7 @@ export const defendPrototype = (
359365
interfaceGuard = undefined,
360366
) => {
361367
const prototype = {};
362-
const methodNames = getMethodNames(behaviorMethods).filter(
368+
const methodNames = getRemotableMethodNames(behaviorMethods).filter(
363369
// By ignoring any method that seems to be a constructor, we can use a
364370
// class.prototype as a behaviorMethods.
365371
key => {
@@ -373,9 +379,9 @@ export const defendPrototype = (
373379
);
374380
},
375381
);
376-
/** @type {Record<PropertyKey, MethodGuard> | undefined} */
382+
/** @type {Record<RemotableMethodName, MethodGuard> | undefined} */
377383
let methodGuards;
378-
/** @type {import('@endo/patterns').DefaultGuardType} */
384+
/** @type {DefaultGuardType} */
379385
let defaultGuards;
380386
if (interfaceGuard) {
381387
const {
@@ -461,12 +467,7 @@ export const defendPrototype = (
461467
);
462468
}
463469

464-
return Far(
465-
tag,
466-
/** @type {T & import('./get-interface.js').GetInterfaceGuard<T>} */ (
467-
prototype
468-
),
469-
);
470+
return Far(tag, /** @type {T & GetInterfaceGuard<T>} */ (prototype));
470471
};
471472
harden(defendPrototype);
472473

packages/exo/src/get-interface.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
// @ts-check
22

3+
/**
4+
* @import {RemotableMethodName} from '@endo/pass-style';
5+
*/
6+
37
/**
48
* The name of the automatically added default meta-method for
59
* obtaining an exo's interface, if it has one.
610
*
711
* Intended to be similar to `GET_METHOD_NAMES` from `@endo/pass-style`.
812
*
9-
* TODO Name to be bikeshed. Perhaps even whether it is a
10-
* string or symbol to be bikeshed. See
11-
* https://github.com/endojs/endo/pull/1809#discussion_r1388052454
13+
* See https://github.com/endojs/endo/pull/1809#discussion_r1388052454
1214
*
13-
* TODO Beware that an exo's interface can change across an upgrade,
15+
* Beware that an exo's interface can change across an upgrade,
1416
* so remotes that cache it can become stale.
1517
*/
1618
export const GET_INTERFACE_GUARD = '__getInterfaceGuard__';
1719

1820
/**
19-
* @template {Record<PropertyKey, CallableFunction>} M
21+
* @template {Record<RemotableMethodName, CallableFunction>} M
2022
* @typedef {{
2123
* [GET_INTERFACE_GUARD]?: () =>
2224
* import('@endo/patterns').InterfaceGuard<{

packages/exo/src/types.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { RemotableBrand } from '@endo/eventual-send';
2-
import type { RemotableObject } from '@endo/pass-style';
2+
import type { RemotableObject, RemotableMethodName } from '@endo/pass-style';
33
import type { InterfaceGuard, MethodGuard, Pattern } from '@endo/patterns';
44
import type { GetInterfaceGuard } from './get-interface.js';
55

@@ -11,7 +11,7 @@ export type MatchConfig = {
1111
redactedIndices: number[];
1212
};
1313
export type FacetName = string;
14-
export type Methods = Record<PropertyKey, CallableFunction>;
14+
export type Methods = Record<RemotableMethodName, CallableFunction>;
1515
export type ClassContext<S = any, M extends Methods = any> = {
1616
state: S;
1717
self: M;

packages/exo/test/heap-classes.test.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// @ts-check
22
import test from '@endo/ses-ava/prepare-endo.js';
33

4-
import { passableSymbolForName } from '@endo/pass-style';
54
import { getInterfaceMethodKeys, M } from '@endo/patterns';
65
import {
76
GET_INTERFACE_GUARD,
@@ -81,25 +80,21 @@ test('test defineExoClass', t => {
8180
t.deepEqual(upCounter[GET_INTERFACE_GUARD]?.(), UpCounterI);
8281
t.deepEqual(getInterfaceMethodKeys(UpCounterI), ['incr']);
8382

84-
const symbolic = passableSymbolForName('symbolic');
8583
const FooI = M.interface('Foo', {
8684
m: M.call().returns(),
87-
[symbolic]: M.call(M.boolean()).returns(),
85+
m2: M.call(M.boolean()).returns(),
8886
});
89-
t.deepEqual(getInterfaceMethodKeys(FooI), [
90-
'm',
91-
passableSymbolForName('symbolic'),
92-
]);
87+
t.deepEqual(getInterfaceMethodKeys(FooI), ['m', 'm2']);
9388
const makeFoo = defineExoClass('Foo', FooI, () => ({}), {
9489
m() {},
95-
[symbolic]() {},
90+
m2() {},
9691
});
9792
const foo = makeFoo();
9893
t.deepEqual(foo[GET_INTERFACE_GUARD]?.(), FooI);
9994
// @ts-expect-error intentional for test
100-
t.throws(() => foo[symbolic]('invalid arg'), {
95+
t.throws(() => foo.m2('invalid arg'), {
10196
message:
102-
'In "[Symbol(symbolic)]" method of (Foo): arg 0: string "invalid arg" - Must be a boolean',
97+
'In "m2" method of (Foo): arg 0: string "invalid arg" - Must be a boolean',
10398
});
10499
});
105100

packages/exo/test/non-enumerable-methods.test.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import test from '@endo/ses-ava/prepare-endo.js';
22

33
import { objectMetaMap } from '@endo/common/object-meta-map.js';
4-
import { passableSymbolForName } from '@endo/pass-style';
54
import { getInterfaceMethodKeys, M } from '@endo/patterns';
65
import { defineExoClass } from '../src/exo-makers.js';
76
import { GET_INTERFACE_GUARD } from '../src/get-interface.js';
@@ -50,28 +49,24 @@ test('test defineExoClass', t => {
5049
t.deepEqual(upCounter[GET_INTERFACE_GUARD](), UpCounterI);
5150
t.deepEqual(getInterfaceMethodKeys(UpCounterI), ['incr']);
5251

53-
const symbolic = passableSymbolForName('symbolic');
5452
const FooI = M.interface('Foo', {
5553
m: M.call().returns(),
56-
[symbolic]: M.call(M.boolean()).returns(),
54+
m2: M.call(M.boolean()).returns(),
5755
});
58-
t.deepEqual(getInterfaceMethodKeys(FooI), [
59-
'm',
60-
passableSymbolForName('symbolic'),
61-
]);
56+
t.deepEqual(getInterfaceMethodKeys(FooI), ['m', 'm2']);
6257
const makeFoo = defineExoClass(
6358
'Foo',
6459
FooI,
6560
() => ({}),
6661
denumerate({
6762
m() {},
68-
[symbolic]() {},
63+
m2() {},
6964
}),
7065
);
7166
const foo = makeFoo();
7267
t.deepEqual(foo[GET_INTERFACE_GUARD](), FooI);
73-
t.throws(() => foo[symbolic]('invalid arg'), {
68+
t.throws(() => foo.m2('invalid arg'), {
7469
message:
75-
'In "[Symbol(symbolic)]" method of (Foo): arg 0: string "invalid arg" - Must be a boolean',
70+
'In "m2" method of (Foo): arg 0: string "invalid arg" - Must be a boolean',
7671
});
7772
});

packages/marshal/src/dot-membrane.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,21 @@
22
/// <reference types="ses"/>
33

44
import { E } from '@endo/eventual-send';
5-
import { isObject, getInterfaceOf, Far, passStyleOf } from '@endo/pass-style';
5+
import {
6+
isObject,
7+
getInterfaceOf,
8+
Far,
9+
passStyleOf,
10+
getRemotableMethodNames,
11+
} from '@endo/pass-style';
612
import { Fail } from '@endo/errors';
713
import { makeMarshal } from './marshal.js';
814

15+
/**
16+
* @import {RemotableMethodName} from '@endo/pass-style';
17+
*/
18+
919
const { fromEntries } = Object;
10-
const { ownKeys } = Reflect;
1120

1221
// TODO(erights): Add Converter type
1322
/** @param {any} [mirrorConverter] */
@@ -58,7 +67,7 @@ const makeConverter = (mirrorConverter = undefined) => {
5867
break;
5968
}
6069
case 'remotable': {
61-
/** @param {PropertyKey} [optVerb] */
70+
/** @param {RemotableMethodName} [optVerb] */
6271
const myMethodToYours =
6372
(optVerb = undefined) =>
6473
(...yourArgs) => {
@@ -91,7 +100,7 @@ const makeConverter = (mirrorConverter = undefined) => {
91100
// minds.
92101
yours = Far(iface, myMethodToYours());
93102
} else {
94-
const myMethodNames = ownKeys(mine);
103+
const myMethodNames = getRemotableMethodNames(mine);
95104
const yourMethods = myMethodNames.map(name => [
96105
name,
97106
myMethodToYours(name),

packages/marshal/src/marshal-stringify.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ harden(stringify);
5353

5454
/**
5555
* @param {string} str
56-
* @returns {unknown}
56+
* @returns {Passable}
5757
*/
5858
const parse = str =>
5959
unserialize(

packages/pass-style/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export {
99

1010
export { getErrorConstructor, isErrorLike } from './src/error.js';
1111

12-
export { getInterfaceOf } from './src/remotable.js';
12+
export { getInterfaceOf, getRemotableMethodNames } from './src/remotable.js';
1313

1414
export {
1515
assertPassableSymbol,

packages/pass-style/src/copyRecord.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
import {
66
assertChecker,
7-
canBeMethod,
87
getOwnDataDescriptor,
98
CX,
109
} from './passStyle-helpers.js';
10+
import { canBeMethod } from './remotable.js';
1111

1212
const { ownKeys } = Reflect;
1313
const { getPrototypeOf, prototype: objectPrototype } = Object;

packages/pass-style/src/passStyle-helpers.js

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/// <reference types="ses"/>
22

3-
/** @import {Checker} from './types.js' */
4-
/** @import {PassStyle} from './types.js' */
3+
/**
4+
* @import {Checker, PassStyle} from './types.js'
5+
*/
56

67
import { X, q } from '@endo/errors';
78

@@ -48,23 +49,6 @@ harden(isTypedArray);
4849

4950
export const PASS_STYLE = Symbol.for('passStyle');
5051

51-
/**
52-
* For a function to be a valid method, it must not be passable.
53-
* Otherwise, we risk confusing pass-by-copy data carrying
54-
* far functions with attempts at far objects with methods.
55-
*
56-
* TODO HAZARD Because we check this on the way to hardening a remotable,
57-
* we cannot yet check that `func` is hardened. However, without
58-
* doing so, it's inheritance might change after the `PASS_STYLE`
59-
* check below.
60-
*
61-
* @param {any} func
62-
* @returns {boolean}
63-
*/
64-
export const canBeMethod = func =>
65-
typeof func === 'function' && !(PASS_STYLE in func);
66-
harden(canBeMethod);
67-
6852
/**
6953
* Below we have a series of predicate functions and their (curried) assertion
7054
* functions. The semantics of the assertion function is just to assert that

0 commit comments

Comments
 (0)