mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-24 18:59:02 -06:00
You're the computer, you sort the fields (#2641)
Change makeStructType() API for sanity. Update callers.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@attic/noms",
|
||||
"license": "Apache-2.0",
|
||||
"version": "60.0.1",
|
||||
"version": "61.0.0",
|
||||
"description": "Noms JS SDK",
|
||||
"repository": "https://github.com/attic-labs/noms",
|
||||
"main": "dist/commonjs/noms.js",
|
||||
|
||||
@@ -117,7 +117,7 @@ suite('validate type', () => {
|
||||
});
|
||||
|
||||
test('struct', () => {
|
||||
const type = makeStructType('Struct', ['x'], [boolType]);
|
||||
const type = makeStructType('Struct', {x: boolType});
|
||||
|
||||
const v = newStruct('Struct', {x: true});
|
||||
assertSubtype(type, v);
|
||||
@@ -178,8 +178,8 @@ suite('validate type', () => {
|
||||
});
|
||||
|
||||
test('struct subtype by name', () => {
|
||||
const namedT = makeStructType('Name', ['x'], [numberType]);
|
||||
const anonT = makeStructType('', ['x'], [numberType]);
|
||||
const namedT = makeStructType('Name', {x: numberType});
|
||||
const anonT = makeStructType('', {x: numberType});
|
||||
const namedV = newStruct('Name', {x: 42});
|
||||
const name2V = newStruct('foo', {x: 42});
|
||||
const anonV = newStruct('', {x: 42});
|
||||
@@ -194,9 +194,9 @@ suite('validate type', () => {
|
||||
});
|
||||
|
||||
test('struct subtype extra fields', () => {
|
||||
const at = makeStructType('', [], []);
|
||||
const bt = makeStructType('', ['x'], [numberType]);
|
||||
const ct = makeStructType('', ['s', 'x'], [stringType, numberType]);
|
||||
const at = makeStructType('', {});
|
||||
const bt = makeStructType('', {x: numberType});
|
||||
const ct = makeStructType('', {s: stringType, x: numberType});
|
||||
const av = newStruct('', {});
|
||||
const bv = newStruct('', {x: 1});
|
||||
const cv = newStruct('', {x: 2, s: 'hi'});
|
||||
@@ -219,22 +219,16 @@ suite('validate type', () => {
|
||||
value: 1,
|
||||
parents: new Set(),
|
||||
});
|
||||
const t1 = makeStructType('Commit',
|
||||
['parents', 'value'],
|
||||
[
|
||||
makeSetType(makeUnionType([])),
|
||||
numberType,
|
||||
]
|
||||
);
|
||||
const t1 = makeStructType('Commit', {
|
||||
parents: makeSetType(makeUnionType([])),
|
||||
value: numberType,
|
||||
});
|
||||
assertSubtype(t1, c1);
|
||||
|
||||
const t11 = makeStructType('Commit',
|
||||
['parents', 'value'],
|
||||
[
|
||||
makeSetType(makeRefType(t1)),
|
||||
numberType,
|
||||
]
|
||||
);
|
||||
const t11 = makeStructType('Commit', {
|
||||
parents: makeSetType(makeRefType(t1)),
|
||||
value: numberType,
|
||||
});
|
||||
assertSubtype(t11, c1);
|
||||
|
||||
const c2 = newStruct('Commit', {
|
||||
@@ -253,18 +247,18 @@ suite('validate type', () => {
|
||||
// x: Cycle<0>,
|
||||
// y: Number,
|
||||
// }
|
||||
const t1 = makeStructType('', ['x', 'y'], [
|
||||
makeCycleType(0),
|
||||
numberType,
|
||||
]);
|
||||
const t1 = makeStructType('', {
|
||||
x: makeCycleType(0),
|
||||
y: numberType,
|
||||
});
|
||||
// struct {
|
||||
// x: Cycle<0>,
|
||||
// y: Number | String,
|
||||
// }
|
||||
const t2 = makeStructType('', ['x', 'y'], [
|
||||
makeCycleType(0),
|
||||
makeUnionType([numberType, stringType]),
|
||||
]);
|
||||
const t2 = makeStructType('', {
|
||||
x: makeCycleType(0),
|
||||
y: makeUnionType([numberType, stringType]),
|
||||
});
|
||||
|
||||
assert.isTrue(isSubtype(t2, t1, []));
|
||||
assert.isFalse(isSubtype(t1, t2, []));
|
||||
@@ -273,10 +267,10 @@ suite('validate type', () => {
|
||||
// x: Cycle<0> | Number,
|
||||
// y: Number | String,
|
||||
// }
|
||||
const t3 = makeStructType('', ['x', 'y'], [
|
||||
makeUnionType([makeCycleType(0), numberType]),
|
||||
makeUnionType([numberType, stringType]),
|
||||
]);
|
||||
const t3 = makeStructType('', {
|
||||
x: makeUnionType([makeCycleType(0), numberType]),
|
||||
y: makeUnionType([numberType, stringType]),
|
||||
});
|
||||
|
||||
assert.isTrue(isSubtype(t3, t1, []));
|
||||
assert.isFalse(isSubtype(t1, t3, []));
|
||||
@@ -288,10 +282,10 @@ suite('validate type', () => {
|
||||
// x: Cycle<0> | Number,
|
||||
// y: Number,
|
||||
// }
|
||||
const t4 = makeStructType('', ['x', 'y'], [
|
||||
makeUnionType([makeCycleType(0), numberType]),
|
||||
numberType,
|
||||
]);
|
||||
const t4 = makeStructType('', {
|
||||
x: makeUnionType([makeCycleType(0), numberType]),
|
||||
y: numberType,
|
||||
});
|
||||
|
||||
assert.isTrue(isSubtype(t4, t1, []));
|
||||
assert.isFalse(isSubtype(t1, t4, []));
|
||||
@@ -313,27 +307,31 @@ suite('validate type', () => {
|
||||
// b: Cycle<1>,
|
||||
// },
|
||||
// }
|
||||
const tb = makeStructType('', ['b'], [
|
||||
makeStructType('', ['c'], [
|
||||
makeCycleType(1),
|
||||
]),
|
||||
]);
|
||||
const tc = makeStructType('', ['c'], [
|
||||
makeStructType('', ['b'], [
|
||||
makeCycleType(1),
|
||||
]),
|
||||
]);
|
||||
const tb = makeStructType('', {
|
||||
b: makeStructType('', {
|
||||
c: makeCycleType(1),
|
||||
}),
|
||||
});
|
||||
const tc = makeStructType('', {
|
||||
c: makeStructType('', {
|
||||
b: makeCycleType(1),
|
||||
}),
|
||||
});
|
||||
|
||||
assert.isFalse(isSubtype(tb, tc, []));
|
||||
assert.isFalse(isSubtype(tc, tb, []));
|
||||
});
|
||||
|
||||
test('isSubtype compound union', () => {
|
||||
const emptyStructType = makeStructType('', [], []);
|
||||
const emptyStructType = makeStructType('', {});
|
||||
const rt = makeListType(emptyStructType);
|
||||
|
||||
const st1 = makeStructType('One', ['a'], [numberType]);
|
||||
const st2 = makeStructType('Two', ['b'], [stringType]);
|
||||
const st1 = makeStructType('One', {
|
||||
a: numberType,
|
||||
});
|
||||
const st2 = makeStructType('Two', {
|
||||
b: stringType,
|
||||
});
|
||||
const ct = makeListType(makeUnionType([st1, st2]));
|
||||
|
||||
assert.isTrue(isSubtype(rt, ct));
|
||||
|
||||
@@ -22,21 +22,19 @@ import Ref from './ref.js';
|
||||
import {newStruct} from './struct.js';
|
||||
|
||||
suite('commit.js', () => {
|
||||
const emptyStructType = makeStructType('', [], []);
|
||||
const emptyStructType = makeStructType('', {});
|
||||
test('new Commit', () => {
|
||||
function assertTypeEquals(e, a) {
|
||||
assert.isTrue(equals(a, e), `Actual: ${a.describe()}\nExpected ${e.describe()}`);
|
||||
}
|
||||
|
||||
const commitFieldNames = ['meta', 'parents', 'value'];
|
||||
|
||||
const commit = new Commit(1, new Set());
|
||||
const at = commit.type;
|
||||
const et = makeStructType('Commit', commitFieldNames, [
|
||||
emptyStructType,
|
||||
makeSetType(makeRefType(makeCycleType(0))),
|
||||
numberType,
|
||||
]);
|
||||
const et = makeStructType('Commit', {
|
||||
meta: emptyStructType,
|
||||
parents: makeSetType(makeRefType(makeCycleType(0))),
|
||||
value: numberType,
|
||||
});
|
||||
assertTypeEquals(et, at);
|
||||
|
||||
// Commiting another Number
|
||||
@@ -48,31 +46,34 @@ suite('commit.js', () => {
|
||||
// Now commit a String
|
||||
const commit3 = new Commit('Hi', new Set([new Ref(commit2)]));
|
||||
const at3 = commit3.type;
|
||||
const et3 = makeStructType('Commit', commitFieldNames, [
|
||||
emptyStructType,
|
||||
makeSetType(makeRefType(makeStructType('Commit', commitFieldNames, [
|
||||
emptyStructType,
|
||||
makeSetType(makeRefType(makeCycleType(0))),
|
||||
makeUnionType([numberType, stringType]),
|
||||
]))),
|
||||
stringType,
|
||||
]);
|
||||
const et3 = makeStructType('Commit', {
|
||||
meta: emptyStructType,
|
||||
parents: makeSetType(makeRefType(makeStructType('Commit', {
|
||||
meta: emptyStructType,
|
||||
parents: makeSetType(makeRefType(makeCycleType(0))),
|
||||
value: makeUnionType([numberType, stringType]),
|
||||
}))),
|
||||
value: stringType,
|
||||
});
|
||||
assertTypeEquals(et3, at3);
|
||||
|
||||
// Now commit a String with MetaInfo
|
||||
const meta = newStruct('Meta', {date: 'some date', number: 9});
|
||||
const metaType = makeStructType('Meta', ['date', 'number'], [stringType, numberType]);
|
||||
const metaType = makeStructType('Meta', {
|
||||
date: stringType,
|
||||
number: numberType,
|
||||
});
|
||||
const commit4 = new Commit('Hi', new Set([new Ref(commit2)]), meta);
|
||||
const at4 = commit4.type;
|
||||
const et4 = makeStructType('Commit', commitFieldNames, [
|
||||
metaType,
|
||||
makeSetType(makeRefType(makeStructType('Commit', commitFieldNames, [
|
||||
makeUnionType([emptyStructType, metaType]),
|
||||
makeSetType(makeRefType(makeCycleType(0))),
|
||||
makeUnionType([numberType, stringType]),
|
||||
]))),
|
||||
stringType,
|
||||
]);
|
||||
const et4 = makeStructType('Commit', {
|
||||
meta: metaType,
|
||||
parents: makeSetType(makeRefType(makeStructType('Commit', {
|
||||
meta: makeUnionType([emptyStructType, metaType]),
|
||||
parents: makeSetType(makeRefType(makeCycleType(0))),
|
||||
value: makeUnionType([numberType, stringType]),
|
||||
}))),
|
||||
value: stringType,
|
||||
});
|
||||
assertTypeEquals(et4, at4);
|
||||
});
|
||||
|
||||
|
||||
@@ -78,24 +78,23 @@ export default class Commit<T: Value> extends Struct {
|
||||
// ../../go/datas/commit.go for the motivation for how this is computed.
|
||||
function makeCommitType(valueType: Type<any>, parentsValueTypes: Type<any>[],
|
||||
metaType: Type<any>, parentsMetaTypes: Type<any>[]): Type<StructDesc> {
|
||||
const fieldNames = ['meta', 'parents', 'value'];
|
||||
const parentsValueUnionType = makeUnionType(parentsValueTypes.concat(valueType));
|
||||
const parentsMetaUnionType = makeUnionType(parentsMetaTypes.concat(metaType));
|
||||
let parentsType;
|
||||
if (equals(parentsValueUnionType, valueType) && equals(parentsMetaUnionType, metaType)) {
|
||||
parentsType = makeSetType(makeRefType(makeCycleType(0)));
|
||||
} else {
|
||||
parentsType = makeSetType(makeRefType(makeStructType('Commit', fieldNames, [
|
||||
parentsMetaUnionType,
|
||||
makeSetType(makeRefType(makeCycleType(0))),
|
||||
parentsValueUnionType,
|
||||
])));
|
||||
parentsType = makeSetType(makeRefType(makeStructType('Commit', {
|
||||
meta: parentsMetaUnionType,
|
||||
parents: makeSetType(makeRefType(makeCycleType(0))),
|
||||
value: parentsValueUnionType,
|
||||
})));
|
||||
}
|
||||
return makeStructType('Commit', fieldNames, [
|
||||
metaType,
|
||||
parentsType,
|
||||
valueType,
|
||||
]);
|
||||
return makeStructType('Commit', {
|
||||
meta: metaType,
|
||||
parents: parentsType,
|
||||
value: valueType,
|
||||
});
|
||||
}
|
||||
|
||||
function valueTypesFromParents(parents: Set<any>, fieldName: string): Type<any>[] {
|
||||
|
||||
@@ -61,19 +61,16 @@ suite('Encode human readable types', () => {
|
||||
});
|
||||
|
||||
test('struct', () => {
|
||||
const type = makeStructType('S1',
|
||||
['x', 'y'],
|
||||
[
|
||||
numberType,
|
||||
stringType,
|
||||
]
|
||||
);
|
||||
const type = makeStructType('S1', {
|
||||
x: numberType,
|
||||
y: stringType,
|
||||
});
|
||||
assertWriteType('struct S1 {\n x: Number,\n y: String,\n}', type);
|
||||
});
|
||||
|
||||
|
||||
test('list of struct', () => {
|
||||
const type = makeStructType('S3', ['x'], [numberType]);
|
||||
const type = makeStructType('S3', {x: numberType});
|
||||
assertWriteType('List<struct S3 {\n x: Number,\n}>', makeListType(type));
|
||||
});
|
||||
|
||||
@@ -87,20 +84,14 @@ suite('Encode human readable types', () => {
|
||||
// }
|
||||
// }
|
||||
|
||||
const a = makeStructType('A',
|
||||
['b', 'c', 'd'],
|
||||
[
|
||||
makeCycleType(0),
|
||||
makeListType(makeCycleType(0)),
|
||||
makeStructType('D',
|
||||
['e', 'f'],
|
||||
[
|
||||
makeCycleType(0),
|
||||
makeCycleType(1),
|
||||
]
|
||||
),
|
||||
]
|
||||
);
|
||||
const a = makeStructType('A', {
|
||||
b: makeCycleType(0),
|
||||
c: makeListType(makeCycleType(0)),
|
||||
d: makeStructType('D', {
|
||||
e: makeCycleType(0),
|
||||
f: makeCycleType(1),
|
||||
}),
|
||||
});
|
||||
|
||||
assertWriteType(`struct A {
|
||||
b: Cycle<0>,
|
||||
@@ -130,13 +121,10 @@ suite('Encode human readable types', () => {
|
||||
// b: Cycle<1>
|
||||
// }
|
||||
|
||||
const a = makeStructType('A',
|
||||
['a', 'b'],
|
||||
[
|
||||
makeCycleType(0),
|
||||
makeCycleType(1),
|
||||
]
|
||||
);
|
||||
const a = makeStructType('A', {
|
||||
a: makeCycleType(0),
|
||||
b: makeCycleType(1),
|
||||
});
|
||||
|
||||
assertWriteType(`struct A {
|
||||
a: Cycle<0>,
|
||||
|
||||
@@ -539,7 +539,7 @@ suite('Encoding', () => {
|
||||
});
|
||||
|
||||
test('list of union with type', () => {
|
||||
const structType = makeStructType('S', ['x'], [numberType]);
|
||||
const structType = makeStructType('S', {x: numberType});
|
||||
|
||||
assertEncoding([
|
||||
uint8(ListKind), uint8(UnionKind), uint32(2) /* len */, uint8(BoolKind), uint8(TypeKind), false,
|
||||
@@ -567,13 +567,10 @@ suite('Encoding', () => {
|
||||
});
|
||||
|
||||
test('recursive struct', () => {
|
||||
const structType = makeStructType('A6',
|
||||
['cs', 'v'],
|
||||
[
|
||||
makeListType(makeCycleType(0)),
|
||||
numberType,
|
||||
]
|
||||
);
|
||||
const structType = makeStructType('A6', {
|
||||
cs: makeListType(makeCycleType(0)),
|
||||
v: numberType,
|
||||
});
|
||||
|
||||
assertEncoding([
|
||||
uint8(StructKind), 'A6', uint32(2) /* len */, 'cs', uint8(ListKind), uint8(CycleKind), uint32(0), 'v', uint8(NumberKind),
|
||||
|
||||
@@ -84,13 +84,10 @@ suite('Struct', () => {
|
||||
});
|
||||
|
||||
test('createStructClass', () => {
|
||||
const typeA = makeStructType('A',
|
||||
['b', 'c'],
|
||||
[
|
||||
numberType,
|
||||
stringType,
|
||||
]
|
||||
);
|
||||
const typeA = makeStructType('A', {
|
||||
b: numberType,
|
||||
c: stringType,
|
||||
});
|
||||
const A = createStructClass(typeA);
|
||||
const a = new A({b: 1, c: 'hi'});
|
||||
assert.instanceOf(a, Struct);
|
||||
@@ -100,13 +97,10 @@ suite('Struct', () => {
|
||||
});
|
||||
|
||||
test('type validation', () => {
|
||||
const type = makeStructType('S1',
|
||||
['o', 'x'],
|
||||
[
|
||||
stringType,
|
||||
boolType,
|
||||
]
|
||||
);
|
||||
const type = makeStructType('S1', {
|
||||
o: stringType,
|
||||
x: boolType,
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
newStructWithType(type, ['hi', 1]);
|
||||
@@ -123,13 +117,10 @@ suite('Struct', () => {
|
||||
// b: Bool
|
||||
// l: List<S>
|
||||
// }
|
||||
const type = makeStructType('S',
|
||||
['b', 'l'],
|
||||
[
|
||||
boolType,
|
||||
makeListType(makeCycleType(0)),
|
||||
]
|
||||
);
|
||||
const type = makeStructType('S', {
|
||||
b: boolType,
|
||||
l: makeListType(makeCycleType(0)),
|
||||
});
|
||||
|
||||
const emptyList = new List([]);
|
||||
newStructWithType(type, [true, emptyList]);
|
||||
@@ -218,7 +209,11 @@ suite('Struct', () => {
|
||||
assert.notEqual(s.hash, 'hash');
|
||||
|
||||
assert.isTrue(equals(s.type,
|
||||
makeStructType('', ['chunks', 'hash', 'type'], [stringType, stringType, stringType])));
|
||||
makeStructType('', {
|
||||
chunks: stringType,
|
||||
hash: stringType,
|
||||
type: stringType,
|
||||
})));
|
||||
assert.deepEqual(s.chunks, []);
|
||||
assert.instanceOf(s.hash, Hash);
|
||||
});
|
||||
|
||||
@@ -264,13 +264,11 @@ export function newStructWithValues<T: Struct>(type: Type<any>, values: Value[])
|
||||
}
|
||||
|
||||
function computeTypeForStruct(name: string, data: StructData): Type<StructDesc> {
|
||||
const fieldNames = Object.keys(data);
|
||||
const fieldTypes = new Array(fieldNames.length);
|
||||
fieldNames.sort();
|
||||
for (let i = 0; i < fieldNames.length; i++) {
|
||||
fieldTypes[i] = getTypeOfValue(data[fieldNames[i]]);
|
||||
const fields = {};
|
||||
for (const k in data) {
|
||||
fields[k] = getTypeOfValue(data[k]);
|
||||
}
|
||||
return makeStructType(name, fieldNames, fieldTypes);
|
||||
return makeStructType(name, fields);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -82,14 +82,14 @@ suite('TypeCache', () => {
|
||||
});
|
||||
|
||||
test('struct', () => {
|
||||
const st = makeStructType('Foo',
|
||||
['bar', 'foo'],
|
||||
[stringType, numberType]
|
||||
);
|
||||
const st2 = makeStructType('Foo',
|
||||
['bar', 'foo'],
|
||||
[stringType, numberType]
|
||||
);
|
||||
const st = makeStructType('Foo', {
|
||||
bar: stringType,
|
||||
foo: numberType,
|
||||
});
|
||||
const st2 = makeStructType('Foo', {
|
||||
bar: stringType,
|
||||
foo: numberType,
|
||||
});
|
||||
|
||||
assert.strictEqual(st, st2);
|
||||
});
|
||||
@@ -110,19 +110,15 @@ suite('TypeCache', () => {
|
||||
});
|
||||
|
||||
test('Cyclic Struct', () => {
|
||||
const st = makeStructType('Foo',
|
||||
['foo'],
|
||||
[
|
||||
makeRefType(makeCycleType(0)),
|
||||
]);
|
||||
const st = makeStructType('Foo', {
|
||||
foo: makeRefType(makeCycleType(0)),
|
||||
});
|
||||
assert.isFalse(st.hasUnresolvedCycle([]));
|
||||
assert.strictEqual(st, st.desc.fields[0].type.desc.elemTypes[0]);
|
||||
|
||||
const st2 = makeStructType('Foo',
|
||||
['foo'],
|
||||
[
|
||||
makeRefType(makeCycleType(0)),
|
||||
]);
|
||||
const st2 = makeStructType('Foo', {
|
||||
foo: makeRefType(makeCycleType(0)),
|
||||
});
|
||||
assert.isFalse(st2.hasUnresolvedCycle([]));
|
||||
assert.strictEqual(st, st2);
|
||||
});
|
||||
@@ -130,7 +126,9 @@ suite('TypeCache', () => {
|
||||
test('Cyclic Unions', () => {
|
||||
const ut = makeUnionType([makeCycleType(0), numberType, stringType, boolType, blobType,
|
||||
valueType, typeType]);
|
||||
const st = makeStructType('Foo', ['foo'], [ut]);
|
||||
const st = makeStructType('Foo', {
|
||||
foo: ut,
|
||||
});
|
||||
|
||||
assert.strictEqual(ut.desc.elemTypes[0].kind, Kind.Cycle);
|
||||
assert.strictEqual(st, st.desc.fields[0].type.desc.elemTypes[1]);
|
||||
@@ -140,7 +138,9 @@ suite('TypeCache', () => {
|
||||
// types.
|
||||
const ut2 = makeUnionType([numberType, stringType, boolType, blobType, valueType, typeType,
|
||||
makeCycleType(0)]);
|
||||
const st2 = makeStructType('Foo', ['foo'], [ut]);
|
||||
const st2 = makeStructType('Foo', {
|
||||
foo: ut,
|
||||
});
|
||||
|
||||
assert.strictEqual(ut2.desc.elemTypes[0].kind, Kind.Cycle);
|
||||
assert.strictEqual(st2, st2.desc.fields[0].type.desc.elemTypes[1]);
|
||||
@@ -152,8 +152,12 @@ suite('TypeCache', () => {
|
||||
|
||||
test('Invalid Cycles and Unions', () => {
|
||||
assert.throws(() => {
|
||||
makeStructType('A', ['a'], [makeStructType('A', ['a'], [makeCycleType(1)])]);
|
||||
});
|
||||
makeStructType('A', {
|
||||
a: makeStructType('A', {
|
||||
a: makeCycleType(1),
|
||||
}),
|
||||
});
|
||||
}, 'unrolled cycle types are not supported; ahl owes you a beer');
|
||||
});
|
||||
|
||||
test('Invalid Crazy Cycles and Unions', () => {
|
||||
@@ -171,9 +175,13 @@ suite('TypeCache', () => {
|
||||
* }
|
||||
*/
|
||||
assert.throws(() => {
|
||||
makeStructType('A', ['a'], [makeUnionType(
|
||||
[makeCycleType(0), makeStructType('A', ['a'], [makeCycleType(0), makeCycleType(1)])]
|
||||
)]);
|
||||
makeStructType('A', {
|
||||
a: makeUnionType([
|
||||
makeCycleType(0), makeStructType('A', {
|
||||
a: makeUnionType([makeCycleType(0), makeCycleType(1)]),
|
||||
}),
|
||||
]),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -86,10 +86,18 @@ export default class TypeCache {
|
||||
return notNull(trie.t);
|
||||
}
|
||||
|
||||
makeStructType(name: string, fieldNames: string[], fieldTypes: Type<any>[]): Type<StructDesc> {
|
||||
makeStructType(name: string, fields: { [key: string]: Type<any> }): Type<StructDesc> {
|
||||
const fieldNames = Object.keys(fields).sort();
|
||||
const fieldTypes = fieldNames.map(n => fields[n]);
|
||||
return this.makeStructTypeQuickly(name, fieldNames, fieldTypes);
|
||||
}
|
||||
|
||||
makeStructTypeQuickly(name: string, fieldNames: Array<string>, fieldTypes: Array<Type<any>>):
|
||||
Type<StructDesc> {
|
||||
if (fieldNames.length !== fieldTypes.length) {
|
||||
throw new Error('Field names and types must be of equal length');
|
||||
}
|
||||
|
||||
verifyStructName(name);
|
||||
verifyFieldNames(fieldNames);
|
||||
|
||||
|
||||
@@ -31,13 +31,10 @@ suite('Type', () => {
|
||||
|
||||
const mapType = makeMapType(stringType, numberType);
|
||||
const setType = makeSetType(stringType);
|
||||
const mahType = makeStructType('MahStruct',
|
||||
['Field1', 'Field2'],
|
||||
[
|
||||
stringType,
|
||||
boolType,
|
||||
]
|
||||
);
|
||||
const mahType = makeStructType('MahStruct', {
|
||||
Field1: stringType,
|
||||
Field2: boolType,
|
||||
});
|
||||
const mapRef = db.writeValue(mapType).targetHash;
|
||||
const setRef = db.writeValue(setType).targetHash;
|
||||
const mahRef = db.writeValue(mahType).targetHash;
|
||||
@@ -83,7 +80,7 @@ suite('Type', () => {
|
||||
test('verify struct field name', () => {
|
||||
function assertInvalid(n: string) {
|
||||
assert.throw(() => {
|
||||
makeStructType('S', [n], [stringType]);
|
||||
makeStructType('S', {[n]: stringType});
|
||||
});
|
||||
}
|
||||
assertInvalid('');
|
||||
@@ -97,7 +94,7 @@ suite('Type', () => {
|
||||
assertInvalid('💩');
|
||||
|
||||
function assertValid(n: string) {
|
||||
makeStructType('S', [n], [stringType]);
|
||||
makeStructType('S', {[n]: stringType});
|
||||
}
|
||||
assertValid('a');
|
||||
assertValid('A');
|
||||
@@ -109,7 +106,7 @@ suite('Type', () => {
|
||||
test('verify struct name', () => {
|
||||
function assertInvalid(n: string) {
|
||||
assert.throw(() => {
|
||||
makeStructType(n, [], []);
|
||||
makeStructType(n, {});
|
||||
});
|
||||
}
|
||||
assertInvalid(' ');
|
||||
@@ -122,7 +119,7 @@ suite('Type', () => {
|
||||
assertInvalid('💩');
|
||||
|
||||
function assertValid(n: string) {
|
||||
makeStructType(n, [], []);
|
||||
makeStructType(n, {});
|
||||
}
|
||||
assertValid('');
|
||||
assertValid('a');
|
||||
@@ -145,16 +142,24 @@ suite('Type', () => {
|
||||
});
|
||||
|
||||
test('union with cycle', () => {
|
||||
const inodeType = makeStructType('Inode', ['attr', 'contents'], [
|
||||
makeStructType('Attr', ['ctime', 'mode', 'mtime'], [numberType, numberType, numberType]),
|
||||
makeUnionType([
|
||||
makeStructType('Directory', ['entries'], [
|
||||
makeMapType(stringType, makeCycleType(1)),
|
||||
]),
|
||||
makeStructType('File', ['data'], [blobType]),
|
||||
makeStructType('Symlink', ['targetPath'], [stringType]),
|
||||
const inodeType = makeStructType('Inode', {
|
||||
attr: makeStructType('Attr', {
|
||||
ctime: numberType,
|
||||
mode: numberType,
|
||||
mtime: numberType,
|
||||
}),
|
||||
contents: makeUnionType([
|
||||
makeStructType('Directory', {
|
||||
entries: makeMapType(stringType, makeCycleType(1)),
|
||||
}),
|
||||
makeStructType('File', {
|
||||
data: blobType,
|
||||
}),
|
||||
makeStructType('Symlink', {
|
||||
targetPath: stringType,
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
});
|
||||
|
||||
const vr: any = null;
|
||||
const t1 = notNull(inodeType.desc.getField('contents'));
|
||||
|
||||
@@ -195,9 +195,9 @@ export function makeRefType(elemType: Type<any>): Type<CompoundDesc> {
|
||||
return staticTypeCache.getCompoundType(Kind.Ref, elemType);
|
||||
}
|
||||
|
||||
export function makeStructType(name: string, fieldNames: string[], fieldTypes: Type<any>[]):
|
||||
export function makeStructType(name: string, fields: {[key: string]: Type<any>}) :
|
||||
Type<StructDesc> {
|
||||
return staticTypeCache.makeStructType(name, fieldNames, fieldTypes);
|
||||
return staticTypeCache.makeStructType(name, fields);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -232,6 +232,6 @@ export default class ValueDecoder {
|
||||
fieldNames[i] = this._r.readString();
|
||||
fieldTypes[i] = this.readType();
|
||||
}
|
||||
return this._tc.makeStructType(name, fieldNames, fieldTypes);
|
||||
return this._tc.makeStructTypeQuickly(name, fieldNames, fieldTypes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,14 +109,11 @@ suite('walk', () => {
|
||||
});
|
||||
|
||||
test('struct', async () => {
|
||||
const t = makeStructType('Thing',
|
||||
['foo', 'list', 'num'],
|
||||
[
|
||||
stringType,
|
||||
makeListType(numberType),
|
||||
numberType,
|
||||
]
|
||||
);
|
||||
const t = makeStructType('Thing', {
|
||||
foo: stringType,
|
||||
list: makeListType(numberType),
|
||||
num: numberType,
|
||||
});
|
||||
|
||||
const c = createStructClass(t);
|
||||
const val = new c({
|
||||
|
||||
@@ -139,14 +139,11 @@ function createNumber(i: number): Value {
|
||||
return i;
|
||||
}
|
||||
|
||||
const structType = makeStructType('S1',
|
||||
['bool', 'num', 'str'],
|
||||
[
|
||||
boolType,
|
||||
numberType,
|
||||
stringType,
|
||||
]
|
||||
);
|
||||
const structType = makeStructType('S1', {
|
||||
bool: boolType,
|
||||
num: numberType,
|
||||
str: stringType,
|
||||
});
|
||||
|
||||
function createStruct(i: number): Value {
|
||||
return newStructWithType(structType,
|
||||
|
||||
@@ -31,40 +31,25 @@ main().catch(ex => {
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
const imageType = makeStructType('',
|
||||
['height', 'source', 'width'],
|
||||
[
|
||||
numberType,
|
||||
stringType,
|
||||
numberType,
|
||||
]
|
||||
);
|
||||
const imageType = makeStructType('', {
|
||||
height: numberType,
|
||||
width: numberType,
|
||||
source: stringType,
|
||||
});
|
||||
|
||||
const photoType = makeStructType('',
|
||||
['id', 'images'],
|
||||
[
|
||||
stringType,
|
||||
makeListType(imageType),
|
||||
]
|
||||
);
|
||||
const photoType = makeStructType('', {
|
||||
id: stringType,
|
||||
images: makeListType(imageType),
|
||||
});
|
||||
|
||||
const placeType = makeStructType('',
|
||||
['place'],
|
||||
[
|
||||
makeStructType('',
|
||||
['location'],
|
||||
[
|
||||
makeStructType('',
|
||||
['latitude', 'longitude'],
|
||||
[
|
||||
numberType,
|
||||
numberType,
|
||||
]
|
||||
),
|
||||
]
|
||||
),
|
||||
]
|
||||
);
|
||||
const placeType = makeStructType('', {
|
||||
place: makeStructType('', {
|
||||
location: makeStructType('', {
|
||||
latitude: numberType,
|
||||
longitude: numberType,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const inSpec = DatasetSpec.parse(args._[0]);
|
||||
|
||||
@@ -30,15 +30,11 @@ const args = argv
|
||||
const sizes = ['t', 's', 'm', 'l', 'o'];
|
||||
const flickrNum = makeUnionType([stringType, numberType]);
|
||||
const sizeTypes = sizes.map(s =>
|
||||
makeStructType('',
|
||||
['height_' + s, 'url_' + s, 'width_' + s],
|
||||
[
|
||||
flickrNum,
|
||||
stringType,
|
||||
flickrNum,
|
||||
]
|
||||
)
|
||||
);
|
||||
makeStructType('', {
|
||||
['height_' + s]: flickrNum,
|
||||
['width_' + s]: flickrNum,
|
||||
['url_' + s]: stringType,
|
||||
}));
|
||||
|
||||
// This is effectively:
|
||||
// union {
|
||||
@@ -68,11 +64,7 @@ const imageType = makeUnionType(sizeTypes.map(st => {
|
||||
newFields[name] = type;
|
||||
});
|
||||
|
||||
const fieldNames = Object.keys(newFields);
|
||||
fieldNames.sort();
|
||||
const fieldTypes = fieldNames.map(fn => newFields[fn]);
|
||||
|
||||
return makeStructType('', fieldNames, fieldTypes);
|
||||
return makeStructType('', newFields);
|
||||
}));
|
||||
|
||||
const nsInSecond = 10e9;
|
||||
|
||||
@@ -43,12 +43,12 @@ const args = argv
|
||||
// entries: Map<String, Cycle<0> | File>,
|
||||
// }
|
||||
|
||||
const fileType = makeStructType('File', ['content'], [makeRefType(blobType)]);
|
||||
const directoryType = makeStructType('Directory',
|
||||
['entries'],
|
||||
[
|
||||
makeMapType(stringType, makeUnionType([fileType, makeCycleType(0)])),
|
||||
]);
|
||||
const fileType = makeStructType('File', {
|
||||
content: makeRefType(blobType),
|
||||
});
|
||||
const directoryType = makeStructType('Directory', {
|
||||
entries: makeMapType(stringType, makeUnionType([fileType, makeCycleType(0)])),
|
||||
});
|
||||
|
||||
const File = createStructClass(fileType);
|
||||
const Directory = createStructClass(directoryType);
|
||||
|
||||
Reference in New Issue
Block a user