mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-31 03:18:43 -06:00
add noms.assert module
This commit is contained in:
14
js2/src/assert.js
Normal file
14
js2/src/assert.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/* @flow */
|
||||
|
||||
'use strict';
|
||||
|
||||
export function invariant(exp: boolean, message: string = 'Invariant violated') {
|
||||
if (!exp) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
export function notNull<T>(v: ?T): T {
|
||||
invariant(v !== null && v !== undefined, 'Unexpected null value');
|
||||
return v;
|
||||
}
|
||||
35
js2/src/assert_test.js
Normal file
35
js2/src/assert_test.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/* @flow */
|
||||
|
||||
'use strict';
|
||||
|
||||
import {suite, test} from 'mocha';
|
||||
import {assert} from 'chai';
|
||||
import {invariant, notNull} from './assert.js';
|
||||
|
||||
class Foo {
|
||||
doNothing() {}
|
||||
}
|
||||
|
||||
function doSomething() {}
|
||||
|
||||
suite('assert', () => {
|
||||
test('invariant', () => {
|
||||
invariant(true);
|
||||
assert.throws(() => {
|
||||
invariant(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('notNull', () => {
|
||||
let t: ?Foo = null;
|
||||
assert.throws(() => {
|
||||
notNull(t);
|
||||
});
|
||||
|
||||
t = new Foo();
|
||||
doSomething(); // might have nullified t;
|
||||
let t2: Foo = notNull(t); // shouldn't throw
|
||||
t2.doNothing();
|
||||
});
|
||||
});
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import Chunk from './chunk.js';
|
||||
import Ref from './ref.js';
|
||||
import {invariant} from './assert.js';
|
||||
|
||||
const sha1Size = 20;
|
||||
const chunkLengthSize = 4; // uint32
|
||||
@@ -44,9 +45,7 @@ export function deserialize(buffer: ArrayBuffer): Array<Chunk> {
|
||||
|
||||
let totalLenth = buffer.byteLength;
|
||||
for (let offset = 0; offset < totalLenth;) {
|
||||
if (buffer.byteLength - offset < chunkHeaderSize) {
|
||||
throw new Error('Invalid chunk buffer');
|
||||
}
|
||||
invariant(buffer.byteLength - offset >= chunkHeaderSize, 'Invalid chunk buffer');
|
||||
|
||||
let refArray = new Uint8Array(buffer, offset, sha1Size);
|
||||
let ref = new Ref(new Uint8Array(refArray));
|
||||
@@ -57,15 +56,12 @@ export function deserialize(buffer: ArrayBuffer): Array<Chunk> {
|
||||
let chunkLength = sizeArray[0];
|
||||
offset += chunkLengthSize;
|
||||
|
||||
if (offset + chunkLength > totalLenth) {
|
||||
throw new Error('Invalid chunk buffer');
|
||||
}
|
||||
invariant(offset + chunkLength <= totalLenth, 'Invalid chunk buffer');
|
||||
|
||||
let dataArray = new Uint8Array(buffer, offset, chunkLength);
|
||||
let chunk = new Chunk(new Uint8Array(dataArray)); // Makes a slice (copy) of the byte sequence from buffer.
|
||||
if (!chunk.ref.equals(ref)) {
|
||||
throw new Error('Serialized ref !== computed ref');
|
||||
}
|
||||
|
||||
invariant(chunk.ref.equals(ref), 'Serialized ref !== computed ref');
|
||||
|
||||
offset += chunkLength;
|
||||
chunks.push(chunk);
|
||||
|
||||
@@ -6,9 +6,10 @@ import Chunk from './chunk.js';
|
||||
import Ref from './ref.js';
|
||||
import type {ChunkStore} from './chunk_store.js';
|
||||
import type {NomsKind} from './noms_kind.js';
|
||||
import {Field, makeCompoundTypeRef, makePrimitiveTypeRef, makeStructTypeRef, makeTypeRef, makeUnresolvedTypeRef, StructDesc, TypeRef} from './type_ref.js';
|
||||
import {invariant, notNull} from './assert.js';
|
||||
import {isPrimitiveKind, Kind} from './noms_kind.js';
|
||||
import {lookupPackage, Package, readPackage} from './package.js';
|
||||
import {Field, makeCompoundTypeRef, makePrimitiveTypeRef, makeStructTypeRef, makeTypeRef, makeUnresolvedTypeRef, StructDesc, TypeRef} from './type_ref.js';
|
||||
|
||||
const typedTag = 't ';
|
||||
|
||||
@@ -33,53 +34,39 @@ class JsonArrayReader {
|
||||
|
||||
readString(): string {
|
||||
let next = this.read();
|
||||
if (typeof next === 'string') {
|
||||
return next;
|
||||
}
|
||||
throw new Error('Serialization error: expected string, got ' + typeof next);
|
||||
invariant(typeof next === 'string');
|
||||
return next;
|
||||
}
|
||||
|
||||
readBool(): boolean {
|
||||
let next = this.read();
|
||||
if (typeof next === 'boolean') {
|
||||
return next;
|
||||
}
|
||||
throw new Error('Serialization error: expected boolean, got ' + typeof next);
|
||||
invariant(typeof next === 'boolean');
|
||||
return next;
|
||||
}
|
||||
|
||||
readNumber(): number {
|
||||
let next = this.read();
|
||||
invariant(typeof next === 'number');
|
||||
return next;
|
||||
}
|
||||
|
||||
readOrdinal(): number {
|
||||
let next = this.read();
|
||||
if (typeof next === 'number' && next >= 0) {
|
||||
return next;
|
||||
}
|
||||
|
||||
throw new Error('Serialization error: expected ordinal, got ' + typeof next);
|
||||
return this.readNumber();
|
||||
}
|
||||
|
||||
readArray(): Array<any> {
|
||||
let next = this.read();
|
||||
if (next instanceof Array) {
|
||||
return next;
|
||||
}
|
||||
|
||||
throw new Error('Serialization error: expected Array');
|
||||
invariant(Array.isArray(next));
|
||||
return next;
|
||||
}
|
||||
|
||||
readKind(): NomsKind {
|
||||
let next = this.read();
|
||||
if (typeof next === 'number') {
|
||||
return next;
|
||||
}
|
||||
throw new Error('Serialization error: expected NomsKind, got ' + typeof next);
|
||||
return this.readNumber();
|
||||
}
|
||||
|
||||
readRef(): Ref {
|
||||
let next = this.read();
|
||||
if (typeof next === 'string') {
|
||||
return Ref.parse(next);
|
||||
}
|
||||
|
||||
throw new Error('Serialization error: expected Ref, got ' + typeof next);
|
||||
let next = this.readString();
|
||||
return Ref.parse(next);
|
||||
}
|
||||
|
||||
readTypeRefAsTag(): TypeRef {
|
||||
@@ -231,20 +218,14 @@ class JsonArrayReader {
|
||||
}
|
||||
}
|
||||
|
||||
if (pkg) {
|
||||
let typeDef = pkg.types[ordinal];
|
||||
if (typeDef.kind === Kind.Enum) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
if (typeDef.kind !== Kind.Struct) {
|
||||
throw new Error('Attempt to resolve non-struct struct kind');
|
||||
}
|
||||
|
||||
return this.readStruct(typeDef, t, pkg);
|
||||
} else {
|
||||
throw new Error('Woah, got a null pkg. pkgRef: ' + pkgRef.toString() + ' ordinal: ' + ordinal);
|
||||
pkg = notNull(pkg);
|
||||
let typeDef = pkg.types[ordinal];
|
||||
if (typeDef.kind === Kind.Enum) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
invariant(typeDef.kind === Kind.Struct);
|
||||
return this.readStruct(typeDef, t, pkg);
|
||||
}
|
||||
|
||||
readTypeRefAsValue(pkg: ?Package): TypeRef {
|
||||
@@ -289,53 +270,47 @@ class JsonArrayReader {
|
||||
if (ordinal === -1) {
|
||||
let namespace = this.readString();
|
||||
let name = this.readString();
|
||||
if (!pkgRef.isEmpty()) {
|
||||
throw new Error('Unresolved TypeRefs may not have a package ref');
|
||||
}
|
||||
invariant(pkgRef.isEmpty(), 'Unresolved TypeRefs may not have a package ref');
|
||||
|
||||
return makeUnresolvedTypeRef(namespace, name);
|
||||
}
|
||||
|
||||
return makeTypeRef(pkgRef, ordinal);
|
||||
}
|
||||
default: {
|
||||
if (!isPrimitiveKind(k)) {
|
||||
throw new Error('Not implemented: ' + k);
|
||||
}
|
||||
return makePrimitiveTypeRef(k);
|
||||
}
|
||||
}
|
||||
|
||||
invariant(isPrimitiveKind(k));
|
||||
return makePrimitiveTypeRef(k);
|
||||
|
||||
}
|
||||
|
||||
async readStruct(typeDef: TypeRef, typeRef: TypeRef, pkg: Package): Promise<any> {
|
||||
// TODO FixupTypeRef?
|
||||
// TODO Make read of sub-values parallel.
|
||||
let desc = typeDef.desc;
|
||||
if (desc instanceof StructDesc) {
|
||||
let s: { [key: string]: any } = Object.create(null);
|
||||
s._typeRef = typeDef; // TODO: Need a better way to add typeRef
|
||||
invariant(desc instanceof StructDesc);
|
||||
|
||||
for (let field of desc.fields) {
|
||||
if (field.optional) {
|
||||
let b = this.readBool();
|
||||
if (b) {
|
||||
let v = await this.readValueWithoutTag(field.t, pkg);
|
||||
s[field.name] = v;
|
||||
}
|
||||
} else {
|
||||
let s: { [key: string]: any } = Object.create(null);
|
||||
s._typeRef = typeDef; // TODO: Need a better way to add typeRef
|
||||
|
||||
for (let field of desc.fields) {
|
||||
if (field.optional) {
|
||||
let b = this.readBool();
|
||||
if (b) {
|
||||
let v = await this.readValueWithoutTag(field.t, pkg);
|
||||
s[field.name] = v;
|
||||
}
|
||||
} else {
|
||||
let v = await this.readValueWithoutTag(field.t, pkg);
|
||||
s[field.name] = v;
|
||||
}
|
||||
|
||||
if (desc.union.length > 0) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
return s;
|
||||
} else {
|
||||
throw new Error('Attempt to read struct without StructDesc typeref');
|
||||
}
|
||||
|
||||
if (desc.union.length > 0) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,10 @@ import MemoryStore from './memory_store.js';
|
||||
import Ref from './ref.js';
|
||||
import type {ChunkStore} from './chunk_store.js';
|
||||
import type {NomsKind} from './noms_kind.js';
|
||||
import {invariant} from './assert.js';
|
||||
import {isPrimitiveKind, Kind} from './noms_kind.js';
|
||||
import {makePrimitiveTypeRef, StructDesc, TypeRef} from './type_ref.js';
|
||||
import {lookupPackage, Package} from './package.js';
|
||||
import {makePrimitiveTypeRef, StructDesc, TypeRef} from './type_ref.js';
|
||||
|
||||
const typedTag = 't ';
|
||||
|
||||
@@ -77,76 +78,57 @@ class JsonArrayWriter {
|
||||
this.write(v); // TODO: Verify value fits in type
|
||||
break;
|
||||
case Kind.List: {
|
||||
if (v instanceof Array) {
|
||||
let w2 = new JsonArrayWriter(this._cs);
|
||||
let elemType = t.elemTypes[0];
|
||||
v.forEach(sv => w2.writeValue(sv, elemType));
|
||||
this.write(w2.array);
|
||||
} else {
|
||||
throw new Error('Attempt to serialize non-list as list');
|
||||
}
|
||||
|
||||
invariant(Array.isArray(v));
|
||||
let w2 = new JsonArrayWriter(this._cs);
|
||||
let elemType = t.elemTypes[0];
|
||||
v.forEach(sv => w2.writeValue(sv, elemType));
|
||||
this.write(w2.array);
|
||||
break;
|
||||
}
|
||||
case Kind.Map: {
|
||||
if (v instanceof Map) {
|
||||
let w2 = new JsonArrayWriter(this._cs);
|
||||
let keyType = t.elemTypes[0];
|
||||
let valueType = t.elemTypes[1];
|
||||
let elems = [];
|
||||
v.forEach((v, k) => {
|
||||
elems.push(k);
|
||||
});
|
||||
elems = orderValuesByRef(keyType, elems);
|
||||
elems.forEach(elem => {
|
||||
w2.writeValue(elem, keyType);
|
||||
w2.writeValue(v.get(elem), valueType);
|
||||
});
|
||||
this.write(w2.array);
|
||||
} else {
|
||||
throw new Error('Attempt to serialize non-map as maps');
|
||||
}
|
||||
|
||||
invariant(v instanceof Map);
|
||||
let w2 = new JsonArrayWriter(this._cs);
|
||||
let keyType = t.elemTypes[0];
|
||||
let valueType = t.elemTypes[1];
|
||||
let elems = [];
|
||||
v.forEach((v, k) => {
|
||||
elems.push(k);
|
||||
});
|
||||
elems = orderValuesByRef(keyType, elems);
|
||||
elems.forEach(elem => {
|
||||
w2.writeValue(elem, keyType);
|
||||
w2.writeValue(v.get(elem), valueType);
|
||||
});
|
||||
this.write(w2.array);
|
||||
break;
|
||||
}
|
||||
case Kind.Package: {
|
||||
if (v instanceof Package) {
|
||||
let ptr = makePrimitiveTypeRef(Kind.TypeRef);
|
||||
let w2 = new JsonArrayWriter(this._cs);
|
||||
v.types.forEach(type => w2.writeValue(type, ptr));
|
||||
this.write(w2.array);
|
||||
let w3 = new JsonArrayWriter(this._cs);
|
||||
v.dependencies.forEach(ref => w3.writeRef(ref));
|
||||
this.write(w3.array);
|
||||
} else {
|
||||
throw new Error('Attempt to serialize non-package as package');
|
||||
}
|
||||
|
||||
invariant(v instanceof Package);
|
||||
let ptr = makePrimitiveTypeRef(Kind.TypeRef);
|
||||
let w2 = new JsonArrayWriter(this._cs);
|
||||
v.types.forEach(type => w2.writeValue(type, ptr));
|
||||
this.write(w2.array);
|
||||
let w3 = new JsonArrayWriter(this._cs);
|
||||
v.dependencies.forEach(ref => w3.writeRef(ref));
|
||||
this.write(w3.array);
|
||||
break;
|
||||
}
|
||||
case Kind.Set: {
|
||||
if (v instanceof Set) {
|
||||
let w2 = new JsonArrayWriter(this._cs);
|
||||
let elemType = t.elemTypes[0];
|
||||
let elems = [];
|
||||
v.forEach(v => {
|
||||
elems.push(v);
|
||||
});
|
||||
elems = orderValuesByRef(elemType, elems);
|
||||
elems.forEach(elem => w2.writeValue(elem, elemType));
|
||||
this.write(w2.array);
|
||||
} else {
|
||||
throw new Error('Attempt to serialize non-set as set');
|
||||
}
|
||||
|
||||
invariant(v instanceof Set);
|
||||
let w2 = new JsonArrayWriter(this._cs);
|
||||
let elemType = t.elemTypes[0];
|
||||
let elems = [];
|
||||
v.forEach(v => {
|
||||
elems.push(v);
|
||||
});
|
||||
elems = orderValuesByRef(elemType, elems);
|
||||
elems.forEach(elem => w2.writeValue(elem, elemType));
|
||||
this.write(w2.array);
|
||||
break;
|
||||
}
|
||||
case Kind.TypeRef:
|
||||
if (v instanceof TypeRef) {
|
||||
this.writeTypeRefAsValue(v);
|
||||
} else {
|
||||
throw new Error('Attempt to serialize non-typeref as typeref');
|
||||
}
|
||||
invariant(v instanceof TypeRef);
|
||||
this.writeTypeRefAsValue(v);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Not implemented');
|
||||
@@ -171,26 +153,22 @@ class JsonArrayWriter {
|
||||
}
|
||||
case Kind.Struct: {
|
||||
let desc = t.desc;
|
||||
if (desc instanceof StructDesc) {
|
||||
this.write(t.name);
|
||||
let fieldWriter = new JsonArrayWriter(this._cs);
|
||||
desc.fields.forEach(field => {
|
||||
fieldWriter.write(field.name);
|
||||
fieldWriter.writeTypeRefAsValue(field.t);
|
||||
fieldWriter.write(field.optional);
|
||||
});
|
||||
this.write(fieldWriter.array);
|
||||
let choiceWriter = new JsonArrayWriter(this._cs);
|
||||
desc.union.forEach(choice => {
|
||||
choiceWriter.write(choice.name);
|
||||
choiceWriter.writeTypeRefAsValue(choice.t);
|
||||
choiceWriter.write(choice.optional);
|
||||
});
|
||||
this.write(choiceWriter.array);
|
||||
} else {
|
||||
throw new Error('Attempt to serialize non-struct typeref as struct type-ref');
|
||||
}
|
||||
|
||||
invariant(desc instanceof StructDesc);
|
||||
this.write(t.name);
|
||||
let fieldWriter = new JsonArrayWriter(this._cs);
|
||||
desc.fields.forEach(field => {
|
||||
fieldWriter.write(field.name);
|
||||
fieldWriter.writeTypeRefAsValue(field.t);
|
||||
fieldWriter.write(field.optional);
|
||||
});
|
||||
this.write(fieldWriter.array);
|
||||
let choiceWriter = new JsonArrayWriter(this._cs);
|
||||
desc.union.forEach(choice => {
|
||||
choiceWriter.write(choice.name);
|
||||
choiceWriter.writeTypeRefAsValue(choice.t);
|
||||
choiceWriter.write(choice.optional);
|
||||
});
|
||||
this.write(choiceWriter.array);
|
||||
break;
|
||||
}
|
||||
case Kind.Unresolved: {
|
||||
@@ -211,9 +189,7 @@ class JsonArrayWriter {
|
||||
}
|
||||
|
||||
default: {
|
||||
if (!isPrimitiveKind(k)) {
|
||||
throw new Error('Not implemented.');
|
||||
}
|
||||
invariant(isPrimitiveKind(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,11 +209,11 @@ function orderValuesByRef(t: TypeRef, a: Array<any>): Array<any> {
|
||||
}
|
||||
|
||||
function encodeNomsValue(v: any, t: TypeRef): Chunk {
|
||||
// if (v instanceof Package) {
|
||||
// if (v.dependencies.length > 0) {
|
||||
// throw new Error('Not implemented');
|
||||
// }
|
||||
// }
|
||||
if (v instanceof Package) {
|
||||
if (v.dependencies.length > 0) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
|
||||
let ms = new MemoryStore(); // TODO: This should be passed in.
|
||||
let w = new JsonArrayWriter(ms);
|
||||
|
||||
@@ -6,6 +6,7 @@ import Chunk from './chunk.js';
|
||||
import fetch from 'isomorphic-fetch';
|
||||
import Ref from './ref.js';
|
||||
import {deserialize} from './chunk_serializer.js';
|
||||
import {invariant} from './assert.js';
|
||||
|
||||
type ReadRequest = {
|
||||
resolve: (c: Chunk) => void,
|
||||
@@ -94,9 +95,7 @@ export default class HttpStore {
|
||||
}
|
||||
});
|
||||
|
||||
if (response.status !== 200) {
|
||||
throw new Error('Buffered read failed: ' + response.status);
|
||||
}
|
||||
invariant(response.status === 200, 'Buffered read failed: ' + response.status);
|
||||
|
||||
let blob = await response.blob();
|
||||
let buffer = await blobToBuffer(blob);
|
||||
|
||||
@@ -6,16 +6,16 @@ import Chunk from './chunk.js';
|
||||
import HttpStore from './http_store.js';
|
||||
import MemoryStore from './memory_store.js';
|
||||
import Ref from './ref.js';
|
||||
import {readValue} from './decode.js';
|
||||
import {encodeNomsValue} from './encode.js';
|
||||
import {readValue} from './decode.js';
|
||||
import {TypeRef} from './type_ref.js';
|
||||
|
||||
export {
|
||||
Chunk,
|
||||
readValue,
|
||||
encodeNomsValue,
|
||||
HttpStore,
|
||||
MemoryStore,
|
||||
readValue,
|
||||
Ref,
|
||||
TypeRef
|
||||
};
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import {readValue} from './decode.js';
|
||||
import Ref from './ref.js';
|
||||
import type {ChunkStore} from './chunk_store.js';
|
||||
import {encodeNomsValue} from './encode.js';
|
||||
import {invariant} from './assert.js';
|
||||
import {Kind} from './noms_kind.js';
|
||||
import {makePrimitiveTypeRef, TypeRef} from './type_ref.js';
|
||||
import {readValue} from './decode.js';
|
||||
|
||||
const packageTypeRef = makePrimitiveTypeRef(Kind.Package);
|
||||
|
||||
@@ -46,12 +47,9 @@ function registerPackage(p: Package) {
|
||||
|
||||
async function readPackage(r: Ref, cs: ChunkStore): Promise<Package> {
|
||||
let p = await readValue(r, cs);
|
||||
if (p instanceof Package) {
|
||||
registerPackage(p);
|
||||
return p;
|
||||
} else {
|
||||
throw new Error('Non-package found where package expected.');
|
||||
}
|
||||
invariant(p instanceof Package);
|
||||
registerPackage(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
export {lookupPackage, Package, readPackage, registerPackage};
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import {isPrimitiveKind, Kind} from './noms_kind.js';
|
||||
import Ref from './ref.js';
|
||||
import type {NomsKind} from './noms_kind.js';
|
||||
import {invariant} from './assert.js';
|
||||
import {isPrimitiveKind, Kind} from './noms_kind.js';
|
||||
|
||||
type TypeDesc = {
|
||||
kind: NomsKind;
|
||||
@@ -161,19 +162,13 @@ class TypeRef {
|
||||
}
|
||||
|
||||
get packageRef(): Ref {
|
||||
if (this._desc instanceof UnresolvedDesc) {
|
||||
return this._desc._pkgRef;
|
||||
}
|
||||
|
||||
throw new Error('PackageRef only works on unresolved type refs');
|
||||
invariant(this._desc instanceof UnresolvedDesc);
|
||||
return this._desc._pkgRef;
|
||||
}
|
||||
|
||||
get ordinal(): number {
|
||||
if (this._desc instanceof UnresolvedDesc) {
|
||||
return this._desc._ordinal;
|
||||
}
|
||||
|
||||
throw new Error('Ordinal has not been set');
|
||||
invariant(this._desc instanceof UnresolvedDesc);
|
||||
return this._desc._ordinal;
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
@@ -198,11 +193,8 @@ class TypeRef {
|
||||
}
|
||||
|
||||
get elemTypes(): Array<TypeRef> {
|
||||
if (this._desc instanceof CompoundDesc) {
|
||||
return this._desc.elemTypes;
|
||||
}
|
||||
|
||||
throw new Error('Only CompoundDesc have elemTypes');
|
||||
invariant(this._desc instanceof CompoundDesc);
|
||||
return this._desc.elemTypes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,16 +224,10 @@ function makePrimitiveTypeRef(k: NomsKind): TypeRef {
|
||||
|
||||
function makeCompoundTypeRef(k: NomsKind, ...elemTypes: Array<TypeRef>): TypeRef {
|
||||
if (elemTypes.length === 1) {
|
||||
if (k === Kind.Map) {
|
||||
throw new Error('Map requires 2 element types');
|
||||
}
|
||||
invariant(k !== Kind.Map, 'Map requires 2 element types');
|
||||
} else {
|
||||
if (k !== Kind.Map) {
|
||||
throw new Error('Only Map can have multiple element types');
|
||||
}
|
||||
if (elemTypes.length !== 2) {
|
||||
throw new Error('Map requires 2 element types');
|
||||
}
|
||||
invariant(k === Kind.Map, 'Only Map can have multiple element types');
|
||||
invariant(elemTypes.length === 2, 'Map requires 2 element types');
|
||||
}
|
||||
|
||||
return buildType('', new CompoundDesc(k, elemTypes));
|
||||
|
||||
Reference in New Issue
Block a user